summaryrefslogtreecommitdiff
path: root/sysdeps/posix
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps/posix')
-rw-r--r--sysdeps/posix/alarm.c2
-rw-r--r--sysdeps/posix/clock.c2
-rw-r--r--sysdeps/posix/clock_getres.c4
-rw-r--r--sysdeps/posix/closedir.c4
-rw-r--r--sysdeps/posix/ctermid.c2
-rw-r--r--sysdeps/posix/cuserid.c2
-rw-r--r--sysdeps/posix/dirfd.c7
-rw-r--r--sysdeps/posix/dirstream.h2
-rw-r--r--sysdeps/posix/dl-fileid.h2
-rw-r--r--sysdeps/posix/dup.c6
-rw-r--r--sysdeps/posix/dup2.c2
-rw-r--r--sysdeps/posix/euidaccess.c2
-rw-r--r--sysdeps/posix/fdopendir.c4
-rw-r--r--sysdeps/posix/flock.c2
-rw-r--r--sysdeps/posix/fpathconf.c23
-rw-r--r--sysdeps/posix/gai_strerror.c2
-rw-r--r--sysdeps/posix/getaddrinfo.c718
-rw-r--r--sysdeps/posix/getcwd.c22
-rw-r--r--sysdeps/posix/getdtsz.c2
-rw-r--r--sysdeps/posix/gethostname.c4
-rw-r--r--sysdeps/posix/getpagesize.c2
-rw-r--r--sysdeps/posix/gettimeofday.c2
-rw-r--r--sysdeps/posix/isatty.c2
-rw-r--r--sysdeps/posix/isfdtype.c2
-rw-r--r--sysdeps/posix/killpg.c2
-rw-r--r--sysdeps/posix/libc_fatal.c28
-rw-r--r--sysdeps/posix/mkfifo.c2
-rw-r--r--sysdeps/posix/mkfifoat.c2
-rw-r--r--sysdeps/posix/nice.c2
-rw-r--r--sysdeps/posix/open64.c2
-rw-r--r--sysdeps/posix/opendir.c159
-rw-r--r--sysdeps/posix/pathconf.c23
-rw-r--r--sysdeps/posix/pause.c18
-rw-r--r--sysdeps/posix/posix_fallocate.c2
-rw-r--r--sysdeps/posix/posix_fallocate64.c2
-rw-r--r--sysdeps/posix/pread.c2
-rw-r--r--sysdeps/posix/pread64.c3
-rw-r--r--sysdeps/posix/preadv.c91
-rw-r--r--sysdeps/posix/preadv2.c42
-rw-r--r--sysdeps/posix/preadv64.c31
-rw-r--r--sysdeps/posix/preadv64v2.c41
-rw-r--r--sysdeps/posix/preadv_common.c85
-rw-r--r--sysdeps/posix/profil.c3
-rw-r--r--sysdeps/posix/pwrite.c2
-rw-r--r--sysdeps/posix/pwrite64.c2
-rw-r--r--sysdeps/posix/pwritev.c79
-rw-r--r--sysdeps/posix/pwritev2.c42
-rw-r--r--sysdeps/posix/pwritev64.c31
-rw-r--r--sysdeps/posix/pwritev64v2.c42
-rw-r--r--sysdeps/posix/pwritev_common.c74
-rw-r--r--sysdeps/posix/raise.c2
-rw-r--r--sysdeps/posix/readdir.c7
-rw-r--r--sysdeps/posix/readdir_r.c7
-rw-r--r--sysdeps/posix/readv.c3
-rw-r--r--sysdeps/posix/remove.c2
-rw-r--r--sysdeps/posix/rename.c2
-rw-r--r--sysdeps/posix/rewinddir.c2
-rw-r--r--sysdeps/posix/seekdir.c2
-rw-r--r--sysdeps/posix/shm-directory.c2
-rw-r--r--sysdeps/posix/shm-directory.h2
-rw-r--r--sysdeps/posix/shm_open.c38
-rw-r--r--sysdeps/posix/shm_unlink.c2
-rw-r--r--sysdeps/posix/sigblock.c3
-rw-r--r--sysdeps/posix/sigignore.c7
-rw-r--r--sysdeps/posix/sigintr.c3
-rw-r--r--sysdeps/posix/signal.c14
-rw-r--r--sysdeps/posix/sigpause.c28
-rw-r--r--sysdeps/posix/sigset.c61
-rw-r--r--sysdeps/posix/sigsetmask.c2
-rw-r--r--sysdeps/posix/sigsuspend.c2
-rw-r--r--sysdeps/posix/sigwait.c2
-rw-r--r--sysdeps/posix/sleep.c2
-rw-r--r--sysdeps/posix/spawni.c357
-rw-r--r--sysdeps/posix/sprofil.c3
-rw-r--r--sysdeps/posix/sysconf.c5
-rw-r--r--sysdeps/posix/system.c3
-rw-r--r--sysdeps/posix/sysv_signal.c7
-rw-r--r--sysdeps/posix/telldir.c2
-rw-r--r--sysdeps/posix/tempname.c2
-rw-r--r--sysdeps/posix/time.c2
-rw-r--r--sysdeps/posix/timespec_get.c2
-rw-r--r--sysdeps/posix/truncate.c2
-rw-r--r--sysdeps/posix/ttyname.c5
-rw-r--r--sysdeps/posix/ttyname_r.c5
-rw-r--r--sysdeps/posix/ulimit.c2
-rw-r--r--sysdeps/posix/usleep.c2
-rw-r--r--sysdeps/posix/utime.c3
-rw-r--r--sysdeps/posix/utimes.c3
-rw-r--r--sysdeps/posix/wait.c4
-rw-r--r--sysdeps/posix/wait3.c6
-rw-r--r--sysdeps/posix/waitid.c4
-rw-r--r--sysdeps/posix/writev.c3
92 files changed, 1071 insertions, 1180 deletions
diff --git a/sysdeps/posix/alarm.c b/sysdeps/posix/alarm.c
index 47b7477e6d..91543cef18 100644
--- a/sysdeps/posix/alarm.c
+++ b/sysdeps/posix/alarm.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/posix/clock.c b/sysdeps/posix/clock.c
index 04ac806410..52382b72c1 100644
--- a/sysdeps/posix/clock.c
+++ b/sysdeps/posix/clock.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/posix/clock_getres.c b/sysdeps/posix/clock_getres.c
index fb328d78a9..e7924e0891 100644
--- a/sysdeps/posix/clock_getres.c
+++ b/sysdeps/posix/clock_getres.c
@@ -1,5 +1,5 @@
/* clock_getres -- Get the resolution of a POSIX clockid_t.
- Copyright (C) 1999-2016 Free Software Foundation, Inc.
+ Copyright (C) 1999-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -58,7 +58,7 @@ hp_timing_getres (struct timespec *res)
static inline int
realtime_getres (struct timespec *res)
{
- long int clk_tck = sysconf (_SC_CLK_TCK);
+ long int clk_tck = __sysconf (_SC_CLK_TCK);
if (__glibc_likely (clk_tck != -1))
{
diff --git a/sysdeps/posix/closedir.c b/sysdeps/posix/closedir.c
index 960cdec8d3..9b1e698762 100644
--- a/sysdeps/posix/closedir.c
+++ b/sysdeps/posix/closedir.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -49,6 +49,6 @@ __closedir (DIR *dirp)
free ((void *) dirp);
- return close_not_cancel (fd);
+ return __close_nocancel (fd);
}
weak_alias (__closedir, closedir)
diff --git a/sysdeps/posix/ctermid.c b/sysdeps/posix/ctermid.c
index 5efdab6a39..767743b4e8 100644
--- a/sysdeps/posix/ctermid.c
+++ b/sysdeps/posix/ctermid.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/posix/cuserid.c b/sysdeps/posix/cuserid.c
index 5f5ea3a8f7..721c645608 100644
--- a/sysdeps/posix/cuserid.c
+++ b/sysdeps/posix/cuserid.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/posix/dirfd.c b/sysdeps/posix/dirfd.c
index f47aafd83a..5afc9f37e7 100644
--- a/sysdeps/posix/dirfd.c
+++ b/sysdeps/posix/dirfd.c
@@ -1,5 +1,5 @@
/* Return the file descriptor used by a DIR stream. Unix version.
- Copyright (C) 1995-2016 Free Software Foundation, Inc.
+ Copyright (C) 1995-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -22,7 +22,10 @@
#undef dirfd
int
-dirfd (DIR *dirp)
+__dirfd (DIR *dirp)
{
return dirp->fd;
}
+
+weak_alias (__dirfd, dirfd)
+libc_hidden_def (dirfd)
diff --git a/sysdeps/posix/dirstream.h b/sysdeps/posix/dirstream.h
index 87a930d7fe..ae6faf65f5 100644
--- a/sysdeps/posix/dirstream.h
+++ b/sysdeps/posix/dirstream.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1993-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/posix/dl-fileid.h b/sysdeps/posix/dl-fileid.h
index c56e324e65..26bef2f9dc 100644
--- a/sysdeps/posix/dl-fileid.h
+++ b/sysdeps/posix/dl-fileid.h
@@ -1,5 +1,5 @@
/* File identity for the dynamic linker. Generic POSIX.1 version.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/posix/dup.c b/sysdeps/posix/dup.c
index 9525e76749..be6ec4b2bf 100644
--- a/sysdeps/posix/dup.c
+++ b/sysdeps/posix/dup.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -24,7 +24,7 @@
int
__dup (int fd)
{
- return fcntl (fd, F_DUPFD, 0);
+ return __fcntl (fd, F_DUPFD, 0);
}
-
+libc_hidden_def (__dup)
weak_alias (__dup, dup)
diff --git a/sysdeps/posix/dup2.c b/sysdeps/posix/dup2.c
index 9fc65029a8..6e050f5fad 100644
--- a/sysdeps/posix/dup2.c
+++ b/sysdeps/posix/dup2.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/posix/euidaccess.c b/sysdeps/posix/euidaccess.c
index d8878aa28f..ec44b0f696 100644
--- a/sysdeps/posix/euidaccess.c
+++ b/sysdeps/posix/euidaccess.c
@@ -1,5 +1,5 @@
/* Check if effective user id can access file
- Copyright (C) 1990-2016 Free Software Foundation, Inc.
+ Copyright (C) 1990-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/posix/fdopendir.c b/sysdeps/posix/fdopendir.c
index 227174ec54..b72eecc66b 100644
--- a/sysdeps/posix/fdopendir.c
+++ b/sysdeps/posix/fdopendir.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005-2016 Free Software Foundation, Inc.
+/* Copyright (C) 2005-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -38,7 +38,7 @@ __fdopendir (int fd)
}
/* Make sure the descriptor allows for reading. */
- int flags = __fcntl (fd, F_GETFL);
+ int flags = __fcntl64_nocancel (fd, F_GETFL);
if (__glibc_unlikely (flags == -1))
return NULL;
if (__glibc_unlikely ((flags & O_ACCMODE) == O_WRONLY))
diff --git a/sysdeps/posix/flock.c b/sysdeps/posix/flock.c
index c621a5b03e..998bc84866 100644
--- a/sysdeps/posix/flock.c
+++ b/sysdeps/posix/flock.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1992-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/posix/fpathconf.c b/sysdeps/posix/fpathconf.c
index 4aaded14be..a9d164564e 100644
--- a/sysdeps/posix/fpathconf.c
+++ b/sysdeps/posix/fpathconf.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -103,25 +103,22 @@ __fpathconf (int fd, int name)
#endif
case _PC_CHOWN_RESTRICTED:
-#ifdef _POSIX_CHOWN_RESTRICTED
- return _POSIX_CHOWN_RESTRICTED;
-#else
- return -1;
+#if _POSIX_CHOWN_RESTRICTED == -1
+# error "Invalid value for _POSIX_CHOWN_RESTRICTED"
#endif
+ return _POSIX_CHOWN_RESTRICTED;
case _PC_NO_TRUNC:
-#ifdef _POSIX_NO_TRUNC
- return _POSIX_NO_TRUNC;
-#else
- return -1;
+#if _POSIX_NO_TRUNC == -1
+# error "Invalid value for _POSIX_NO_TRUNC"
#endif
+ return _POSIX_NO_TRUNC;
case _PC_VDISABLE:
-#ifdef _POSIX_VDISABLE
- return _POSIX_VDISABLE;
-#else
- return -1;
+#if _POSIX_VDISABLE == -1
+# error "Invalid value for _POSIX_VDISABLE"
#endif
+ return _POSIX_VDISABLE;
case _PC_SYNC_IO:
#ifdef _POSIX_SYNC_IO
diff --git a/sysdeps/posix/gai_strerror.c b/sysdeps/posix/gai_strerror.c
index 151ee08c29..6c2b66bf9f 100644
--- a/sysdeps/posix/gai_strerror.c
+++ b/sysdeps/posix/gai_strerror.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1997-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Philip Blundell <pjb27@cam.ac.uk>, 1997.
diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
index 1ef3f20d98..553833d1f2 100644
--- a/sysdeps/posix/getaddrinfo.c
+++ b/sysdeps/posix/getaddrinfo.c
@@ -1,3 +1,21 @@
+/* Host and service name lookups using Name Service Switch modules.
+ Copyright (C) 1996-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
/* The Inner Net License, Version 2.00
The author(s) grant permission for redistribution and use in source and
@@ -41,7 +59,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <ifaddrs.h>
#include <netdb.h>
#include <nss.h>
-#include <resolv.h>
+#include <resolv/resolv-internal.h>
+#include <resolv/resolv_context.h>
+#include <resolv/res_use_inet6.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdio_ext.h>
@@ -62,13 +82,15 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <not-cancel.h>
#include <nscd/nscd-client.h>
#include <nscd/nscd_proto.h>
-#include <resolv/res_hconf.h>
+#include <scratch_buffer.h>
+#include <inet/net-internal.h>
+
+/* Former AI_IDN_ALLOW_UNASSIGNED and AI_IDN_USE_STD3_ASCII_RULES
+ flags, now ignored. */
+#define DEPRECATED_AI_IDN 0x300
-#ifdef HAVE_LIBIDN
-extern int __idna_to_ascii_lz (const char *input, char **output, int flags);
-extern int __idna_to_unicode_lzlz (const char *input, char **output,
- int flags);
-# include <libidn/idna.h>
+#if IS_IN (libc)
+# define feof_unlocked(fp) __feof_unlocked (fp)
#endif
struct gaih_service
@@ -135,24 +157,24 @@ static const struct addrinfo default_hints =
static int
gaih_inet_serv (const char *servicename, const struct gaih_typeproto *tp,
- const struct addrinfo *req, struct gaih_servtuple *st)
+ const struct addrinfo *req, struct gaih_servtuple *st,
+ struct scratch_buffer *tmpbuf)
{
struct servent *s;
- size_t tmpbuflen = 1024;
struct servent ts;
- char *tmpbuf;
int r;
do
{
- tmpbuf = __alloca (tmpbuflen);
-
- r = __getservbyname_r (servicename, tp->name, &ts, tmpbuf, tmpbuflen,
- &s);
+ r = __getservbyname_r (servicename, tp->name, &ts,
+ tmpbuf->data, tmpbuf->length, &s);
if (r != 0 || s == NULL)
{
if (r == ERANGE)
- tmpbuflen *= 2;
+ {
+ if (!scratch_buffer_grow (tmpbuf))
+ return -EAI_MEMORY;
+ }
else
return -EAI_SERVICE;
}
@@ -168,87 +190,114 @@ gaih_inet_serv (const char *servicename, const struct gaih_typeproto *tp,
return 0;
}
+/* Convert struct hostent to a list of struct gaih_addrtuple objects.
+ h_name is not copied, and the struct hostent object must not be
+ deallocated prematurely. *RESULT must be NULL or a pointer to a
+ linked-list. The new addresses are appended at the end. */
+static bool
+convert_hostent_to_gaih_addrtuple (const struct addrinfo *req,
+ int family,
+ struct hostent *h,
+ struct gaih_addrtuple **result)
+{
+ while (*result)
+ result = &(*result)->next;
+
+ /* Count the number of addresses in h->h_addr_list. */
+ size_t count = 0;
+ for (char **p = h->h_addr_list; *p != NULL; ++p)
+ ++count;
+
+ /* Report no data if no addresses are available, or if the incoming
+ address size is larger than what we can store. */
+ if (count == 0 || h->h_length > sizeof (((struct gaih_addrtuple) {}).addr))
+ return true;
+
+ struct gaih_addrtuple *array = calloc (count, sizeof (*array));
+ if (array == NULL)
+ return false;
+
+ for (size_t i = 0; i < count; ++i)
+ {
+ if (family == AF_INET && req->ai_family == AF_INET6)
+ {
+ /* Perform address mapping. */
+ array[i].family = AF_INET6;
+ memcpy(array[i].addr + 3, h->h_addr_list[i], sizeof (uint32_t));
+ array[i].addr[2] = htonl (0xffff);
+ }
+ else
+ {
+ array[i].family = family;
+ memcpy (array[i].addr, h->h_addr_list[i], h->h_length);
+ }
+ array[i].next = array + i + 1;
+ }
+ array[0].name = h->h_name;
+ array[count - 1].next = NULL;
+
+ *result = array;
+ return true;
+}
+
#define gethosts(_family, _type) \
{ \
- int i; \
- int herrno; \
struct hostent th; \
- struct hostent *h; \
char *localcanon = NULL; \
no_data = 0; \
- while (1) { \
- rc = 0; \
- status = DL_CALL_FCT (fct, (name, _family, &th, tmpbuf, tmpbuflen, \
- &rc, &herrno, NULL, &localcanon)); \
- if (rc != ERANGE || herrno != NETDB_INTERNAL) \
- break; \
- if (!malloc_tmpbuf && __libc_use_alloca (alloca_used + 2 * tmpbuflen)) \
- tmpbuf = extend_alloca_account (tmpbuf, tmpbuflen, 2 * tmpbuflen, \
- alloca_used); \
- else \
- { \
- char *newp = realloc (malloc_tmpbuf ? tmpbuf : NULL, \
- 2 * tmpbuflen); \
- if (newp == NULL) \
- { \
- result = -EAI_MEMORY; \
- goto free_and_return; \
- } \
- tmpbuf = newp; \
- malloc_tmpbuf = true; \
- tmpbuflen = 2 * tmpbuflen; \
- } \
- } \
- if (status == NSS_STATUS_SUCCESS && rc == 0) \
- h = &th; \
- else \
- h = NULL; \
- if (rc != 0) \
+ while (1) \
+ { \
+ status = DL_CALL_FCT (fct, (name, _family, &th, \
+ tmpbuf->data, tmpbuf->length, \
+ &errno, &h_errno, NULL, &localcanon)); \
+ if (status != NSS_STATUS_TRYAGAIN || h_errno != NETDB_INTERNAL \
+ || errno != ERANGE) \
+ break; \
+ if (!scratch_buffer_grow (tmpbuf)) \
+ { \
+ __resolv_context_enable_inet6 (res_ctx, res_enable_inet6); \
+ __resolv_context_put (res_ctx); \
+ result = -EAI_MEMORY; \
+ goto free_and_return; \
+ } \
+ } \
+ if (status == NSS_STATUS_NOTFOUND \
+ || status == NSS_STATUS_TRYAGAIN || status == NSS_STATUS_UNAVAIL) \
{ \
- if (herrno == NETDB_INTERNAL) \
+ if (h_errno == NETDB_INTERNAL) \
{ \
- __set_h_errno (herrno); \
- _res.options |= old_res_options & RES_USE_INET6; \
+ __resolv_context_enable_inet6 (res_ctx, res_enable_inet6); \
+ __resolv_context_put (res_ctx); \
result = -EAI_SYSTEM; \
goto free_and_return; \
} \
- if (herrno == TRY_AGAIN) \
+ if (h_errno == TRY_AGAIN) \
no_data = EAI_AGAIN; \
else \
- no_data = herrno == NO_DATA; \
+ no_data = h_errno == NO_DATA; \
} \
- else if (h != NULL) \
+ else if (status == NSS_STATUS_SUCCESS) \
{ \
- for (i = 0; h->h_addr_list[i]; i++) \
+ if (!convert_hostent_to_gaih_addrtuple (req, _family, &th, &addrmem)) \
{ \
- if (*pat == NULL) \
- { \
- *pat = __alloca (sizeof (struct gaih_addrtuple)); \
- (*pat)->scopeid = 0; \
- } \
- uint32_t *addr = (*pat)->addr; \
- (*pat)->next = NULL; \
- (*pat)->name = i == 0 ? strdupa (h->h_name) : NULL; \
- if (_family == AF_INET && req->ai_family == AF_INET6) \
- { \
- (*pat)->family = AF_INET6; \
- addr[3] = *(uint32_t *) h->h_addr_list[i]; \
- addr[2] = htonl (0xffff); \
- addr[1] = 0; \
- addr[0] = 0; \
- } \
- else \
+ __resolv_context_enable_inet6 (res_ctx, res_enable_inet6); \
+ __resolv_context_put (res_ctx); \
+ result = -EAI_SYSTEM; \
+ goto free_and_return; \
+ } \
+ *pat = addrmem; \
+ \
+ if (localcanon != NULL && canon == NULL) \
+ { \
+ canonbuf = __strdup (localcanon); \
+ if (canonbuf == NULL) \
{ \
- (*pat)->family = _family; \
- memcpy (addr, h->h_addr_list[i], sizeof(_type)); \
+ result = -EAI_SYSTEM; \
+ goto free_and_return; \
} \
- pat = &((*pat)->next); \
+ canon = canonbuf; \
} \
- \
- if (localcanon != NULL && canon == NULL) \
- canon = strdupa (localcanon); \
- \
- if (_family == AF_INET6 && i > 0) \
+ if (_family == AF_INET6 && *pat != NULL) \
got_ipv6 = true; \
} \
}
@@ -265,22 +314,45 @@ typedef enum nss_status (*nss_gethostbyname3_r)
typedef enum nss_status (*nss_getcanonname_r)
(const char *name, char *buffer, size_t buflen, char **result,
int *errnop, int *h_errnop);
-extern service_user *__nss_hosts_database attribute_hidden;
+/* This function is called if a canonical name is requested, but if
+ the service function did not provide it. It tries to obtain the
+ name using getcanonname_r from the same service NIP. If the name
+ cannot be canonicalized, return a copy of NAME. Return NULL on
+ memory allocation failure. The returned string is allocated on the
+ heap; the caller has to free it. */
+static char *
+getcanonname (service_user *nip, struct gaih_addrtuple *at, const char *name)
+{
+ nss_getcanonname_r cfct = __nss_lookup_function (nip, "getcanonname_r");
+ char *s = (char *) name;
+ if (cfct != NULL)
+ {
+ char buf[256];
+ if (DL_CALL_FCT (cfct, (at->name ?: name, buf, sizeof (buf),
+ &s, &errno, &h_errno)) != NSS_STATUS_SUCCESS)
+ /* If the canonical name cannot be determined, use the passed
+ string. */
+ s = (char *) name;
+ }
+ return __strdup (name);
+}
static int
gaih_inet (const char *name, const struct gaih_service *service,
const struct addrinfo *req, struct addrinfo **pai,
- unsigned int *naddrs)
+ unsigned int *naddrs, struct scratch_buffer *tmpbuf)
{
const struct gaih_typeproto *tp = gaih_inet_typeproto;
struct gaih_servtuple *st = (struct gaih_servtuple *) &nullserv;
struct gaih_addrtuple *at = NULL;
- int rc;
bool got_ipv6 = false;
const char *canon = NULL;
const char *orig_name = name;
- size_t alloca_used = 0;
+
+ /* Reserve stack memory for the scratch buffer in the getaddrinfo
+ function. */
+ size_t alloca_used = sizeof (struct scratch_buffer);
if (req->ai_protocol || req->ai_socktype)
{
@@ -315,7 +387,8 @@ gaih_inet (const char *name, const struct gaih_service *service,
st = (struct gaih_servtuple *)
alloca_account (sizeof (struct gaih_servtuple), alloca_used);
- if ((rc = gaih_inet_serv (service->name, tp, req, st)))
+ int rc = gaih_inet_serv (service->name, tp, req, st, tmpbuf);
+ if (__glibc_unlikely (rc != 0))
return rc;
}
else
@@ -340,12 +413,9 @@ gaih_inet (const char *name, const struct gaih_service *service,
alloca_account (sizeof (struct gaih_servtuple),
alloca_used);
- if ((rc = gaih_inet_serv (service->name, tp, req, newp)))
- {
- if (rc)
- continue;
- return rc;
- }
+ if (gaih_inet_serv (service->name,
+ tp, req, newp, tmpbuf) != 0)
+ continue;
*pst = newp;
pst = &(newp->next);
@@ -397,13 +467,10 @@ gaih_inet (const char *name, const struct gaih_service *service,
}
bool malloc_name = false;
- bool malloc_addrmem = false;
struct gaih_addrtuple *addrmem = NULL;
- bool malloc_canonbuf = false;
char *canonbuf = NULL;
- bool malloc_tmpbuf = false;
- char *tmpbuf = NULL;
int result = 0;
+
if (name != NULL)
{
at = alloca_account (sizeof (struct gaih_addrtuple), alloca_used);
@@ -411,35 +478,15 @@ gaih_inet (const char *name, const struct gaih_service *service,
at->scopeid = 0;
at->next = NULL;
-#ifdef HAVE_LIBIDN
if (req->ai_flags & AI_IDN)
{
- int idn_flags = 0;
- if (req->ai_flags & AI_IDN_ALLOW_UNASSIGNED)
- idn_flags |= IDNA_ALLOW_UNASSIGNED;
- if (req->ai_flags & AI_IDN_USE_STD3_ASCII_RULES)
- idn_flags |= IDNA_USE_STD3_ASCII_RULES;
-
- char *p = NULL;
- rc = __idna_to_ascii_lz (name, &p, idn_flags);
- if (rc != IDNA_SUCCESS)
- {
- /* No need to jump to free_and_return here. */
- if (rc == IDNA_MALLOC_ERROR)
- return -EAI_MEMORY;
- if (rc == IDNA_DLOPEN_ERROR)
- return -EAI_SYSTEM;
- return -EAI_IDN_ENCODE;
- }
- /* In case the output string is the same as the input string
- no new string has been allocated. */
- if (p != name)
- {
- name = p;
- malloc_name = true;
- }
+ char *out;
+ result = __idna_to_dns_encoding (name, &out);
+ if (result != 0)
+ return -result;
+ name = out;
+ malloc_name = true;
}
-#endif
if (__inet_aton (name, (struct in_addr *) at->addr) != 0)
{
@@ -466,46 +513,11 @@ gaih_inet (const char *name, const struct gaih_service *service,
{
char *scope_delim = strchr (name, SCOPE_DELIMITER);
int e;
-
- {
- bool malloc_namebuf = false;
- char *namebuf = (char *) name;
-
- if (__glibc_unlikely (scope_delim != NULL))
- {
- if (malloc_name)
- *scope_delim = '\0';
- else
- {
- if (__libc_use_alloca (alloca_used
- + scope_delim - name + 1))
- {
- namebuf = alloca_account (scope_delim - name + 1,
- alloca_used);
- *((char *) __mempcpy (namebuf, name,
- scope_delim - name)) = '\0';
- }
- else
- {
- namebuf = strndup (name, scope_delim - name);
- if (namebuf == NULL)
- {
- assert (!malloc_name);
- return -EAI_MEMORY;
- }
- malloc_namebuf = true;
- }
- }
- }
-
- e = inet_pton (AF_INET6, namebuf, at->addr);
-
- if (malloc_namebuf)
- free (namebuf);
- else if (scope_delim != NULL && malloc_name)
- /* Undo what we did above. */
- *scope_delim = SCOPE_DELIMITER;
- }
+ if (scope_delim == NULL)
+ e = inet_pton (AF_INET6, name, at->addr);
+ else
+ e = __inet_pton_length (AF_INET6, name, scope_delim - name,
+ at->addr);
if (e > 0)
{
if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6)
@@ -522,31 +534,13 @@ gaih_inet (const char *name, const struct gaih_service *service,
goto free_and_return;
}
- if (scope_delim != NULL)
+ if (scope_delim != NULL
+ && __inet6_scopeid_pton ((struct in6_addr *) at->addr,
+ scope_delim + 1,
+ &at->scopeid) != 0)
{
- int try_numericscope = 0;
- if (IN6_IS_ADDR_LINKLOCAL (at->addr)
- || IN6_IS_ADDR_MC_LINKLOCAL (at->addr))
- {
- at->scopeid = if_nametoindex (scope_delim + 1);
- if (at->scopeid == 0)
- try_numericscope = 1;
- }
- else
- try_numericscope = 1;
-
- if (try_numericscope != 0)
- {
- char *end;
- assert (sizeof (uint32_t) <= sizeof (unsigned long));
- at->scopeid = (uint32_t) strtoul (scope_delim + 1, &end,
- 10);
- if (*end != '\0')
- {
- result = -EAI_NONAME;
- goto free_and_return;
- }
- }
+ result = -EAI_NONAME;
+ goto free_and_return;
}
if (req->ai_flags & AI_CANONNAME)
@@ -563,7 +557,8 @@ gaih_inet (const char *name, const struct gaih_service *service,
enum nss_status inet6_status = NSS_STATUS_UNAVAIL;
enum nss_status status = NSS_STATUS_UNAVAIL;
int no_more;
- int old_res_options;
+ struct resolv_context *res_ctx = NULL;
+ bool res_enable_inet6 = false;
/* If we do not have to look for IPv6 addresses or the canonical
name, use the simple, old functions, which do not support
@@ -571,40 +566,21 @@ gaih_inet (const char *name, const struct gaih_service *service,
if (req->ai_family == AF_INET
&& (req->ai_flags & AI_CANONNAME) == 0)
{
- /* Allocate additional room for struct host_data. */
- size_t tmpbuflen = (512 + MAX_NR_ALIASES * sizeof(char*)
- + 16 * sizeof(char));
- assert (tmpbuf == NULL);
- tmpbuf = alloca_account (tmpbuflen, alloca_used);
int rc;
struct hostent th;
struct hostent *h;
- int herrno;
while (1)
{
- rc = __gethostbyname2_r (name, AF_INET, &th, tmpbuf,
- tmpbuflen, &h, &herrno);
- if (rc != ERANGE || herrno != NETDB_INTERNAL)
+ rc = __gethostbyname2_r (name, AF_INET, &th,
+ tmpbuf->data, tmpbuf->length,
+ &h, &h_errno);
+ if (rc != ERANGE || h_errno != NETDB_INTERNAL)
break;
-
- if (!malloc_tmpbuf
- && __libc_use_alloca (alloca_used + 2 * tmpbuflen))
- tmpbuf = extend_alloca_account (tmpbuf, tmpbuflen,
- 2 * tmpbuflen,
- alloca_used);
- else
+ if (!scratch_buffer_grow (tmpbuf))
{
- char *newp = realloc (malloc_tmpbuf ? tmpbuf : NULL,
- 2 * tmpbuflen);
- if (newp == NULL)
- {
- result = -EAI_MEMORY;
- goto free_and_return;
- }
- tmpbuf = newp;
- malloc_tmpbuf = true;
- tmpbuflen = 2 * tmpbuflen;
+ result = -EAI_MEMORY;
+ goto free_and_return;
}
}
@@ -612,54 +588,29 @@ gaih_inet (const char *name, const struct gaih_service *service,
{
if (h != NULL)
{
- int i;
- /* We found data, count the number of addresses. */
- for (i = 0; h->h_addr_list[i]; ++i)
- ;
- if (i > 0 && *pat != NULL)
- --i;
-
- if (__libc_use_alloca (alloca_used
- + i * sizeof (struct gaih_addrtuple)))
- addrmem = alloca_account (i * sizeof (struct gaih_addrtuple),
- alloca_used);
- else
- {
- addrmem = malloc (i
- * sizeof (struct gaih_addrtuple));
- if (addrmem == NULL)
- {
- result = -EAI_MEMORY;
- goto free_and_return;
- }
- malloc_addrmem = true;
- }
-
- /* Now convert it into the list. */
- struct gaih_addrtuple *addrfree = addrmem;
- for (i = 0; h->h_addr_list[i]; ++i)
+ /* We found data, convert it. */
+ if (!convert_hostent_to_gaih_addrtuple
+ (req, AF_INET, h, &addrmem))
{
- if (*pat == NULL)
- {
- *pat = addrfree++;
- (*pat)->scopeid = 0;
- }
- (*pat)->next = NULL;
- (*pat)->family = AF_INET;
- memcpy ((*pat)->addr, h->h_addr_list[i],
- h->h_length);
- pat = &((*pat)->next);
+ result = -EAI_MEMORY;
+ goto free_and_return;
}
+ *pat = addrmem;
+ }
+ else
+ {
+ if (h_errno == NO_DATA)
+ result = -EAI_NODATA;
+ else
+ result = -EAI_NONAME;
+ goto free_and_return;
}
}
else
{
- if (herrno == NETDB_INTERNAL)
- {
- __set_h_errno (herrno);
- result = -EAI_SYSTEM;
- }
- else if (herrno == TRY_AGAIN)
+ if (h_errno == NETDB_INTERNAL)
+ result = -EAI_SYSTEM;
+ else if (h_errno == TRY_AGAIN)
result = -EAI_AGAIN;
else
/* We made requests but they turned out no data.
@@ -682,29 +633,18 @@ gaih_inet (const char *name, const struct gaih_service *service,
{
/* Try to use nscd. */
struct nscd_ai_result *air = NULL;
- int herrno;
- int err = __nscd_getai (name, &air, &herrno);
+ int err = __nscd_getai (name, &air, &h_errno);
if (air != NULL)
{
/* Transform into gaih_addrtuple list. */
bool added_canon = (req->ai_flags & AI_CANONNAME) == 0;
char *addrs = air->addrs;
- if (__libc_use_alloca (alloca_used
- + air->naddrs * sizeof (struct gaih_addrtuple)))
- addrmem = alloca_account (air->naddrs
- * sizeof (struct gaih_addrtuple),
- alloca_used);
- else
+ addrmem = calloc (air->naddrs, sizeof (*addrmem));
+ if (addrmem == NULL)
{
- addrmem = malloc (air->naddrs
- * sizeof (struct gaih_addrtuple));
- if (addrmem == NULL)
- {
- result = -EAI_MEMORY;
- goto free_and_return;
- }
- malloc_addrmem = true;
+ result = -EAI_MEMORY;
+ goto free_and_return;
}
struct gaih_addrtuple *addrfree = addrmem;
@@ -735,22 +675,13 @@ gaih_inet (const char *name, const struct gaih_service *service,
(*pat)->name = NULL;
else if (canonbuf == NULL)
{
- size_t canonlen = strlen (air->canon) + 1;
- if ((req->ai_flags & AI_CANONIDN) != 0
- && __libc_use_alloca (alloca_used + canonlen))
- canonbuf = alloca_account (canonlen, alloca_used);
- else
+ canonbuf = __strdup (air->canon);
+ if (canonbuf == NULL)
{
- canonbuf = malloc (canonlen);
- if (canonbuf == NULL)
- {
- result = -EAI_MEMORY;
- goto free_and_return;
- }
- malloc_canonbuf = true;
+ result = -EAI_MEMORY;
+ goto free_and_return;
}
- canon = (*pat)->name = memcpy (canonbuf, air->canon,
- canonlen);
+ canon = (*pat)->name = canonbuf;
}
if (air->family[i] == AF_INET
@@ -793,9 +724,9 @@ gaih_inet (const char *name, const struct gaih_service *service,
goto free_and_return;
else if (__nss_not_use_nscd_hosts == 0)
{
- if (herrno == NETDB_INTERNAL && errno == ENOMEM)
+ if (h_errno == NETDB_INTERNAL && errno == ENOMEM)
result = -EAI_MEMORY;
- else if (herrno == TRY_AGAIN)
+ else if (h_errno == TRY_AGAIN)
result = -EAI_AGAIN;
else
result = -EAI_SYSTEM;
@@ -813,34 +744,14 @@ gaih_inet (const char *name, const struct gaih_service *service,
no_more = 0;
nip = __nss_hosts_database;
- /* Initialize configurations. */
- if (__glibc_unlikely (!_res_hconf.initialized))
- _res_hconf_init ();
- if (__res_maybe_init (&_res, 0) == -1)
- no_more = 1;
-
/* If we are looking for both IPv4 and IPv6 address we don't
want the lookup functions to automatically promote IPv4
- addresses to IPv6 addresses. Currently this is decided
- by setting the RES_USE_INET6 bit in _res.options. */
- old_res_options = _res.options;
- _res.options &= ~RES_USE_INET6;
-
- size_t tmpbuflen = 1024 + sizeof(struct gaih_addrtuple);
- malloc_tmpbuf = !__libc_use_alloca (alloca_used + tmpbuflen);
- assert (tmpbuf == NULL);
- if (!malloc_tmpbuf)
- tmpbuf = alloca_account (tmpbuflen, alloca_used);
- else
- {
- tmpbuf = malloc (tmpbuflen);
- if (tmpbuf == NULL)
- {
- _res.options |= old_res_options & RES_USE_INET6;
- result = -EAI_MEMORY;
- goto free_and_return;
- }
- }
+ addresses to IPv6 addresses, so we use the no_inet6
+ function variant. */
+ res_ctx = __resolv_context_get ();
+ res_enable_inet6 = __resolv_context_disable_inet6 (res_ctx);
+ if (res_ctx == NULL)
+ no_more = 1;
while (!no_more)
{
@@ -854,44 +765,31 @@ gaih_inet (const char *name, const struct gaih_service *service,
if (fct4 != NULL)
{
- int herrno;
-
while (1)
{
- rc = 0;
- status = DL_CALL_FCT (fct4, (name, pat, tmpbuf,
- tmpbuflen, &rc, &herrno,
+ status = DL_CALL_FCT (fct4, (name, pat,
+ tmpbuf->data, tmpbuf->length,
+ &errno, &h_errno,
NULL));
if (status == NSS_STATUS_SUCCESS)
break;
if (status != NSS_STATUS_TRYAGAIN
- || rc != ERANGE || herrno != NETDB_INTERNAL)
+ || errno != ERANGE || h_errno != NETDB_INTERNAL)
{
- if (herrno == TRY_AGAIN)
+ if (h_errno == TRY_AGAIN)
no_data = EAI_AGAIN;
else
- no_data = herrno == NO_DATA;
+ no_data = h_errno == NO_DATA;
break;
}
- if (!malloc_tmpbuf
- && __libc_use_alloca (alloca_used + 2 * tmpbuflen))
- tmpbuf = extend_alloca_account (tmpbuf, tmpbuflen,
- 2 * tmpbuflen,
- alloca_used);
- else
+ if (!scratch_buffer_grow (tmpbuf))
{
- char *newp = realloc (malloc_tmpbuf ? tmpbuf : NULL,
- 2 * tmpbuflen);
- if (newp == NULL)
- {
- _res.options |= old_res_options & RES_USE_INET6;
- result = -EAI_MEMORY;
- goto free_and_return;
- }
- tmpbuf = newp;
- malloc_tmpbuf = true;
- tmpbuflen = 2 * tmpbuflen;
+ __resolv_context_enable_inet6
+ (res_ctx, res_enable_inet6);
+ __resolv_context_put (res_ctx);
+ result = -EAI_MEMORY;
+ goto free_and_return;
}
}
@@ -985,54 +883,16 @@ gaih_inet (const char *name, const struct gaih_service *service,
if ((req->ai_flags & AI_CANONNAME) != 0
&& canon == NULL)
{
- /* If we need the canonical name, get it
- from the same service as the result. */
- nss_getcanonname_r cfct;
- int herrno;
-
- cfct = __nss_lookup_function (nip,
- "getcanonname_r");
- if (cfct != NULL)
+ canonbuf = getcanonname (nip, at, name);
+ if (canonbuf == NULL)
{
- const size_t max_fqdn_len = 256;
- if ((req->ai_flags & AI_CANONIDN) != 0
- && __libc_use_alloca (alloca_used
- + max_fqdn_len))
- canonbuf = alloca_account (max_fqdn_len,
- alloca_used);
- else
- {
- canonbuf = malloc (max_fqdn_len);
- if (canonbuf == NULL)
- {
- _res.options
- |= old_res_options & RES_USE_INET6;
- result = -EAI_MEMORY;
- goto free_and_return;
- }
- malloc_canonbuf = true;
- }
- char *s;
-
- if (DL_CALL_FCT (cfct, (at->name ?: name,
- canonbuf,
- max_fqdn_len,
- &s, &rc, &herrno))
- == NSS_STATUS_SUCCESS)
- canon = s;
- else
- {
- /* If the canonical name cannot be
- determined, use the passed in
- string. */
- if (malloc_canonbuf)
- {
- free (canonbuf);
- malloc_canonbuf = false;
- }
- canon = name;
- }
+ __resolv_context_enable_inet6
+ (res_ctx, res_enable_inet6);
+ __resolv_context_put (res_ctx);
+ result = -EAI_MEMORY;
+ goto free_and_return;
}
+ canon = canonbuf;
}
status = NSS_STATUS_SUCCESS;
}
@@ -1049,13 +909,17 @@ gaih_inet (const char *name, const struct gaih_service *service,
}
else
{
+ /* Could not locate any of the lookup functions.
+ The NSS lookup code does not consistently set
+ errno, so we need to supply our own error
+ code here. The root cause could either be a
+ resource allocation failure, or a missing
+ service function in the DSO (so it should not
+ be listed in /etc/nsswitch.conf). Assume the
+ former, and return EBUSY. */
status = NSS_STATUS_UNAVAIL;
- /* Could not load any of the lookup functions. Indicate
- an internal error if the failure was due to a system
- error other than the file not being found. We use the
- errno from the last failed callback. */
- if (errno != 0 && errno != ENOENT)
- __set_h_errno (NETDB_INTERNAL);
+ __set_h_errno (NETDB_INTERNAL);
+ __set_errno (EBUSY);
}
}
@@ -1068,9 +932,13 @@ gaih_inet (const char *name, const struct gaih_service *service,
nip = nip->next;
}
- _res.options |= old_res_options & RES_USE_INET6;
+ __resolv_context_enable_inet6 (res_ctx, res_enable_inet6);
+ __resolv_context_put (res_ctx);
- if (h_errno == NETDB_INTERNAL)
+ /* If we have a failure which sets errno, report it using
+ EAI_SYSTEM. */
+ if ((status == NSS_STATUS_TRYAGAIN || status == NSS_STATUS_UNAVAIL)
+ && h_errno == NETDB_INTERNAL)
{
result = -EAI_SYSTEM;
goto free_and_return;
@@ -1144,46 +1012,31 @@ gaih_inet (const char *name, const struct gaih_service *service,
the passed in string. */
canon = orig_name;
-#ifdef HAVE_LIBIDN
- if (req->ai_flags & AI_CANONIDN)
+ bool do_idn = req->ai_flags & AI_CANONIDN;
+ if (do_idn)
{
- int idn_flags = 0;
- if (req->ai_flags & AI_IDN_ALLOW_UNASSIGNED)
- idn_flags |= IDNA_ALLOW_UNASSIGNED;
- if (req->ai_flags & AI_IDN_USE_STD3_ASCII_RULES)
- idn_flags |= IDNA_USE_STD3_ASCII_RULES;
-
char *out;
- int rc = __idna_to_unicode_lzlz (canon, &out, idn_flags);
- if (rc != IDNA_SUCCESS)
+ int rc = __idna_from_dns_encoding (canon, &out);
+ if (rc == 0)
+ canon = out;
+ else if (rc == EAI_IDN_ENCODE)
+ /* Use the punycode name as a fallback. */
+ do_idn = false;
+ else
{
- if (rc == IDNA_MALLOC_ERROR)
- result = -EAI_MEMORY;
- else if (rc == IDNA_DLOPEN_ERROR)
- result = -EAI_SYSTEM;
- else
- result = -EAI_IDN_ENCODE;
+ result = -rc;
goto free_and_return;
}
- /* In case the output string is the same as the input
- string no new string has been allocated and we
- make a copy. */
- if (out == canon)
- goto make_copy;
- canon = out;
}
- else
-#endif
+ if (!do_idn)
{
-#ifdef HAVE_LIBIDN
- make_copy:
-#endif
- if (malloc_canonbuf)
- /* We already allocated the string using malloc. */
- malloc_canonbuf = false;
+ if (canonbuf != NULL)
+ /* We already allocated the string using malloc, but
+ the buffer is now owned by canon. */
+ canonbuf = NULL;
else
{
- canon = strdup (canon);
+ canon = __strdup (canon);
if (canon == NULL)
{
result = -EAI_MEMORY;
@@ -1274,12 +1127,8 @@ gaih_inet (const char *name, const struct gaih_service *service,
free_and_return:
if (malloc_name)
free ((char *) name);
- if (malloc_addrmem)
- free (addrmem);
- if (malloc_canonbuf)
- free (canonbuf);
- if (malloc_tmpbuf)
- free (tmpbuf);
+ free (addrmem);
+ free (canonbuf);
return result;
}
@@ -2341,10 +2190,7 @@ getaddrinfo (const char *name, const char *service,
if (hints->ai_flags
& ~(AI_PASSIVE|AI_CANONNAME|AI_NUMERICHOST|AI_ADDRCONFIG|AI_V4MAPPED
-#ifdef HAVE_LIBIDN
- |AI_IDN|AI_CANONIDN|AI_IDN_ALLOW_UNASSIGNED
- |AI_IDN_USE_STD3_ASCII_RULES
-#endif
+ |AI_IDN|AI_CANONIDN|DEPRECATED_AI_IDN
|AI_NUMERICSERV|AI_ALL))
return EAI_BADFLAGS;
@@ -2414,7 +2260,11 @@ getaddrinfo (const char *name, const char *service,
if (hints->ai_family == AF_UNSPEC || hints->ai_family == AF_INET
|| hints->ai_family == AF_INET6)
{
- last_i = gaih_inet (name, pservice, hints, end, &naddrs);
+ struct scratch_buffer tmpbuf;
+ scratch_buffer_init (&tmpbuf);
+ last_i = gaih_inet (name, pservice, hints, end, &naddrs, &tmpbuf);
+ scratch_buffer_free (&tmpbuf);
+
if (last_i != 0)
{
freeaddrinfo (p);
@@ -2510,9 +2360,9 @@ getaddrinfo (const char *name, const char *service,
{
if (fd != -1)
close_retry:
- close_not_cancel_no_status (fd);
+ __close_nocancel_nostatus (fd);
af = q->ai_family;
- fd = __socket (af, SOCK_DGRAM, IPPROTO_IP);
+ fd = __socket (af, SOCK_DGRAM | SOCK_CLOEXEC, IPPROTO_IP);
}
else
{
@@ -2613,7 +2463,7 @@ getaddrinfo (const char *name, const char *service,
}
if (fd != -1)
- close_not_cancel_no_status (fd);
+ __close_nocancel_nostatus (fd);
/* We got all the source addresses we can get, now sort using
the information. */
diff --git a/sysdeps/posix/getcwd.c b/sysdeps/posix/getcwd.c
index 38cf4e7fc8..b53433a2dc 100644
--- a/sysdeps/posix/getcwd.c
+++ b/sysdeps/posix/getcwd.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -175,8 +175,8 @@ extern char *alloca ();
# include <not-cancel.h>
# include <kernel-features.h>
#else
-# define openat64_not_cancel_3(dfd, name, mode) openat64 (dfd, name, mode)
-# define close_not_cancel_no_status(fd) close (fd)
+# define __openat64_nocancel(dfd, name, mode) openat64 (dfd, name, mode)
+# define __close_nocancel_nostatus(fd) close (fd)
#endif
#ifndef PATH_MAX
@@ -281,13 +281,7 @@ __getcwd (char *buf, size_t size)
while (!(thisdev == rootdev && thisino == rootino))
{
if (__have_atfcts >= 0)
- {
- int mode = O_RDONLY;
-#ifdef O_CLOEXEC
- mode |= O_CLOEXEC;
-#endif
- fd = openat64_not_cancel_3 (fd, "..", mode);
- }
+ fd = __openat64_nocancel (fd, "..", O_RDONLY | O_CLOEXEC);
else
fd = -1;
if (fd >= 0)
@@ -324,7 +318,7 @@ __getcwd (char *buf, size_t size)
}
else
{
- new = realloc ((__ptr_t) dotlist, dotsize * 2 + 1);
+ new = realloc ((void *) dotlist, dotsize * 2 + 1);
if (new == NULL)
goto lose;
dotp = &new[dotsize];
@@ -498,7 +492,7 @@ __getcwd (char *buf, size_t size)
#ifndef __ASSUME_ATFCTS
if (dotlist != dots)
- free ((__ptr_t) dotlist);
+ free ((void *) dotlist);
#endif
size_t used = path + allocated - pathp;
@@ -522,12 +516,12 @@ __getcwd (char *buf, size_t size)
int save_errno = errno;
#ifndef __ASSUME_ATFCTS
if (dotlist != dots)
- free ((__ptr_t) dotlist);
+ free ((void *) dotlist);
#endif
if (dirstream != NULL)
__closedir (dirstream);
if (fd_needs_closing)
- close_not_cancel_no_status (fd);
+ __close_nocancel_nostatus (fd);
#ifndef NO_ALLOCATION
if (buf == NULL)
free (path);
diff --git a/sysdeps/posix/getdtsz.c b/sysdeps/posix/getdtsz.c
index ea1c66ca0b..0da5081575 100644
--- a/sysdeps/posix/getdtsz.c
+++ b/sysdeps/posix/getdtsz.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/posix/gethostname.c b/sysdeps/posix/gethostname.c
index 6ce54e933b..0e29e18617 100644
--- a/sysdeps/posix/gethostname.c
+++ b/sysdeps/posix/gethostname.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1992-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -29,7 +29,7 @@ __gethostname (char *name, size_t len)
struct utsname buf;
size_t node_len;
- if (uname (&buf))
+ if (__uname (&buf))
return -1;
node_len = strlen (buf.nodename) + 1;
diff --git a/sysdeps/posix/getpagesize.c b/sysdeps/posix/getpagesize.c
index 11963ac7a6..6f37dba644 100644
--- a/sysdeps/posix/getpagesize.c
+++ b/sysdeps/posix/getpagesize.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1993-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Brendan Kehoe (brendan@cygnus.com).
diff --git a/sysdeps/posix/gettimeofday.c b/sysdeps/posix/gettimeofday.c
index e6e343c23d..ea00cd387d 100644
--- a/sysdeps/posix/gettimeofday.c
+++ b/sysdeps/posix/gettimeofday.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/posix/isatty.c b/sysdeps/posix/isatty.c
index aaed61af74..a06e7ecad5 100644
--- a/sysdeps/posix/isatty.c
+++ b/sysdeps/posix/isatty.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/posix/isfdtype.c b/sysdeps/posix/isfdtype.c
index e3779b4530..38e7fd4210 100644
--- a/sysdeps/posix/isfdtype.c
+++ b/sysdeps/posix/isfdtype.c
@@ -1,5 +1,5 @@
/* Determine whether descriptor has given property.
- Copyright (C) 1996-2016 Free Software Foundation, Inc.
+ Copyright (C) 1996-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/posix/killpg.c b/sysdeps/posix/killpg.c
index dc3a7f1433..533d2f1722 100644
--- a/sysdeps/posix/killpg.c
+++ b/sysdeps/posix/killpg.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/posix/libc_fatal.c b/sysdeps/posix/libc_fatal.c
index 3c820dab11..89a20080e1 100644
--- a/sysdeps/posix/libc_fatal.c
+++ b/sysdeps/posix/libc_fatal.c
@@ -1,5 +1,5 @@
/* Catastrophic failure reports. Generic POSIX.1 version.
- Copyright (C) 1993-2016 Free Software Foundation, Inc.
+ Copyright (C) 1993-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -64,7 +64,7 @@ struct str_list
/* Abort with an error message. */
void
-__libc_message (int do_abort, const char *fmt, ...)
+__libc_message (enum __libc_message_action action, const char *fmt, ...)
{
va_list ap;
int fd = -1;
@@ -75,11 +75,16 @@ __libc_message (int do_abort, const char *fmt, ...)
FATAL_PREPARE;
#endif
- /* Open a descriptor for /dev/tty unless the user explicitly
- requests errors on standard error. */
- const char *on_2 = __libc_secure_getenv ("LIBC_FATAL_STDERR_");
- if (on_2 == NULL || *on_2 == '\0')
- fd = open_not_cancel_2 (_PATH_TTY, O_RDWR | O_NOCTTY | O_NDELAY);
+ /* Don't call __libc_secure_getenv if we aren't doing backtrace, which
+ may access the corrupted stack. */
+ if ((action & do_backtrace))
+ {
+ /* Open a descriptor for /dev/tty unless the user explicitly
+ requests errors on standard error. */
+ const char *on_2 = __libc_secure_getenv ("LIBC_FATAL_STDERR_");
+ if (on_2 == NULL || *on_2 == '\0')
+ fd = __open_nocancel (_PATH_TTY, O_RDWR | O_NOCTTY | O_NDELAY);
+ }
if (fd == -1)
fd = STDERR_FILENO;
@@ -140,7 +145,7 @@ __libc_message (int do_abort, const char *fmt, ...)
written = WRITEV_FOR_FATAL (fd, iov, nlist, total);
- if (do_abort)
+ if ((action & do_abort))
{
total = ((total + 1 + GLRO(dl_pagesize) - 1)
& ~(GLRO(dl_pagesize) - 1));
@@ -167,9 +172,10 @@ __libc_message (int do_abort, const char *fmt, ...)
va_end (ap);
- if (do_abort)
+ if ((action & do_abort))
{
- BEFORE_ABORT (do_abort, written, fd);
+ if ((action & do_backtrace))
+ BEFORE_ABORT (do_abort, written, fd);
/* Kill the application. */
abort ();
@@ -182,6 +188,6 @@ __libc_fatal (const char *message)
{
/* The loop is added only to keep gcc happy. */
while (1)
- __libc_message (1, "%s", message);
+ __libc_message (do_abort | do_backtrace, "%s", message);
}
libc_hidden_def (__libc_fatal)
diff --git a/sysdeps/posix/mkfifo.c b/sysdeps/posix/mkfifo.c
index 7eea6572ca..eedbf9e28c 100644
--- a/sysdeps/posix/mkfifo.c
+++ b/sysdeps/posix/mkfifo.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/posix/mkfifoat.c b/sysdeps/posix/mkfifoat.c
index 0f910d7441..c54383eab9 100644
--- a/sysdeps/posix/mkfifoat.c
+++ b/sysdeps/posix/mkfifoat.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005-2016 Free Software Foundation, Inc.
+/* Copyright (C) 2005-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/posix/nice.c b/sysdeps/posix/nice.c
index ae82618767..2d907e80e4 100644
--- a/sysdeps/posix/nice.c
+++ b/sysdeps/posix/nice.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1992-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/posix/open64.c b/sysdeps/posix/open64.c
index dc0387b44a..c4209c8cdb 100644
--- a/sysdeps/posix/open64.c
+++ b/sysdeps/posix/open64.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/posix/opendir.c b/sysdeps/posix/opendir.c
index 3e09deb805..bb6bd7cc85 100644
--- a/sysdeps/posix/opendir.c
+++ b/sysdeps/posix/opendir.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -15,24 +15,13 @@
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
-#include <assert.h>
-#include <errno.h>
-#include <limits.h>
-#include <stdbool.h>
-#include <stddef.h>
-#include <stdlib.h>
#include <dirent.h>
#include <fcntl.h>
-#include <sys/param.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <string.h>
+#include <errno.h>
+#include <stdio.h> /* For BUFSIZ. */
+#include <sys/param.h> /* For MIN and MAX. */
-#include <dirstream.h>
#include <not-cancel.h>
-#include <kernel-features.h>
/* The st_blksize value of the directory is used as a hint for the
size of the buffer which receives struct dirent values from the
@@ -40,47 +29,9 @@
file system provides a bogus value. */
#define MAX_DIR_BUFFER_SIZE 1048576U
-/* opendir() must not accidentally open something other than a directory.
- Some OS's have kernel support for that, some don't. In the worst
- case we have to stat() before the open() AND fstat() after.
-
- We have to test at runtime for kernel support since libc may have
- been compiled with different headers to the kernel it's running on.
- This test can't be done reliably in the general case. We'll use
- /dev/null, which if it's not a device lots of stuff will break, as
- a guinea pig. It may be missing in chroot environments, so we
- make sure to fail safe. */
-#ifdef O_DIRECTORY
-# ifdef O_DIRECTORY_WORKS
-# define o_directory_works 1
-# define tryopen_o_directory() while (1) /* This must not be called. */
-# else
-static int o_directory_works;
-
-static void
-tryopen_o_directory (void)
-{
- int serrno = errno;
- int x = open_not_cancel_2 ("/dev/null", O_RDONLY|O_NDELAY|O_DIRECTORY);
-
- if (x >= 0)
- {
- close_not_cancel_no_status (x);
- o_directory_works = -1;
- }
- else if (errno != ENOTDIR)
- o_directory_works = -1;
- else
- o_directory_works = 1;
-
- __set_errno (serrno);
-}
-# endif
-# define EXTRA_FLAGS O_DIRECTORY
-#else
-# define EXTRA_FLAGS 0
-#endif
-
+enum {
+ opendir_oflags = O_RDONLY|O_NDELAY|O_DIRECTORY|O_LARGEFILE|O_CLOEXEC
+};
static bool
invalid_name (const char *name)
@@ -95,33 +46,6 @@ invalid_name (const char *name)
return false;
}
-
-static bool
-need_isdir_precheck (void)
-{
-#ifdef O_DIRECTORY
- /* Test whether O_DIRECTORY works. */
- if (o_directory_works == 0)
- tryopen_o_directory ();
-
- /* We can skip the expensive `stat' call if O_DIRECTORY works. */
- return o_directory_works < 0;
-#endif
- return true;
-}
-
-
-static int
-opendir_oflags (void)
-{
- int flags = O_RDONLY|O_NDELAY|EXTRA_FLAGS|O_LARGEFILE;
-#ifdef O_CLOEXEC
- flags |= O_CLOEXEC;
-#endif
- return flags;
-}
-
-
static DIR *
opendir_tail (int fd)
{
@@ -138,7 +62,7 @@ opendir_tail (int fd)
{
__set_errno (ENOTDIR);
lose:
- close_not_cancel_no_status (fd);
+ __close_nocancel_nostatus (fd);
return NULL;
}
@@ -148,29 +72,12 @@ opendir_tail (int fd)
#if IS_IN (libc)
DIR *
-internal_function
__opendirat (int dfd, const char *name)
{
if (__glibc_unlikely (invalid_name (name)))
return NULL;
- if (need_isdir_precheck ())
- {
- /* We first have to check whether the name is for a directory. We
- cannot do this after the open() call since the open/close operation
- performed on, say, a tape device might have undesirable effects. */
- struct stat64 statbuf;
- if (__glibc_unlikely (__fxstatat64 (_STAT_VER, dfd, name,
- &statbuf, 0) < 0))
- return NULL;
- if (__glibc_unlikely (! S_ISDIR (statbuf.st_mode)))
- {
- __set_errno (ENOTDIR);
- return NULL;
- }
- }
-
- return opendir_tail (openat_not_cancel_3 (dfd, name, opendir_oflags ()));
+ return opendir_tail (__openat_nocancel (dfd, name, opendir_oflags));
}
#endif
@@ -182,54 +89,18 @@ __opendir (const char *name)
if (__glibc_unlikely (invalid_name (name)))
return NULL;
- if (need_isdir_precheck ())
- {
- /* We first have to check whether the name is for a directory. We
- cannot do this after the open() call since the open/close operation
- performed on, say, a tape device might have undesirable effects. */
- struct stat64 statbuf;
- if (__glibc_unlikely (__xstat64 (_STAT_VER, name, &statbuf) < 0))
- return NULL;
- if (__glibc_unlikely (! S_ISDIR (statbuf.st_mode)))
- {
- __set_errno (ENOTDIR);
- return NULL;
- }
- }
-
- return opendir_tail (open_not_cancel_2 (name, opendir_oflags ()));
+ return opendir_tail (__open_nocancel (name, opendir_oflags));
}
weak_alias (__opendir, opendir)
-
-#ifdef __ASSUME_O_CLOEXEC
-# define check_have_o_cloexec(fd) 1
-#else
-static int
-check_have_o_cloexec (int fd)
-{
- if (__have_o_cloexec == 0)
- __have_o_cloexec = (__fcntl (fd, F_GETFD, 0) & FD_CLOEXEC) == 0 ? -1 : 1;
- return __have_o_cloexec > 0;
-}
-#endif
-
-
DIR *
-internal_function
__alloc_dir (int fd, bool close_fd, int flags, const struct stat64 *statp)
{
- /* We always have to set the close-on-exit flag if the user provided
- the file descriptor. Otherwise only if we have no working
- O_CLOEXEC support. */
-#ifdef O_CLOEXEC
- if ((! close_fd && (flags & O_CLOEXEC) == 0)
- || ! check_have_o_cloexec (fd))
-#endif
- {
- if (__builtin_expect (__fcntl (fd, F_SETFD, FD_CLOEXEC), 0) < 0)
+ /* We have to set the close-on-exit flag if the user provided the
+ file descriptor. */
+ if (!close_fd
+ && __glibc_unlikely (__fcntl64_nocancel (fd, F_SETFD, FD_CLOEXEC) < 0))
goto lose;
- }
const size_t default_allocation = (4 * BUFSIZ < sizeof (struct dirent64)
? sizeof (struct dirent64) : 4 * BUFSIZ);
@@ -256,7 +127,7 @@ __alloc_dir (int fd, bool close_fd, int flags, const struct stat64 *statp)
if (close_fd)
{
int save_errno = errno;
- close_not_cancel_no_status (fd);
+ __close_nocancel_nostatus (fd);
__set_errno (save_errno);
}
return NULL;
diff --git a/sysdeps/posix/pathconf.c b/sysdeps/posix/pathconf.c
index f65d5018ea..0f893ec1ba 100644
--- a/sysdeps/posix/pathconf.c
+++ b/sysdeps/posix/pathconf.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -101,25 +101,22 @@ __pathconf (const char *path, int name)
#endif
case _PC_CHOWN_RESTRICTED:
-#ifdef _POSIX_CHOWN_RESTRICTED
- return _POSIX_CHOWN_RESTRICTED;
-#else
- return -1;
+#if _POSIX_CHOWN_RESTRICTED == -1
+# error "Invalid value for _POSIX_CHOWN_RESTRICTED"
#endif
+ return _POSIX_CHOWN_RESTRICTED;
case _PC_NO_TRUNC:
-#ifdef _POSIX_NO_TRUNC
- return _POSIX_NO_TRUNC;
-#else
- return -1;
+#if _POSIX_NO_TRUNC == -1
+# error "Invalid value for _POSIX_NO_TRUNC"
#endif
+ return _POSIX_NO_TRUNC;
case _PC_VDISABLE:
-#ifdef _POSIX_VDISABLE
- return _POSIX_VDISABLE;
-#else
- return -1;
+#if _POSIX_VDISABLE == -1
+# error "Invalid value for _POSIX_VDISABLE"
#endif
+ return _POSIX_VDISABLE;
case _PC_SYNC_IO:
#ifdef _POSIX_SYNC_IO
diff --git a/sysdeps/posix/pause.c b/sysdeps/posix/pause.c
index f1ecc4f98b..2b9eca2192 100644
--- a/sysdeps/posix/pause.c
+++ b/sysdeps/posix/pause.c
@@ -1,5 +1,5 @@
/* pause -- suspend the process until a signal arrives. POSIX.1 version.
- Copyright (C) 2003-2016 Free Software Foundation, Inc.
+ Copyright (C) 2003-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -19,6 +19,7 @@
#include <signal.h>
#include <unistd.h>
#include <sysdep-cancel.h>
+#include <sigsetops.h>
/* Suspend the process until a signal arrives.
This always returns -1 and sets errno to EINTR. */
@@ -39,18 +40,3 @@ __libc_pause (void)
weak_alias (__libc_pause, pause)
LIBC_CANCEL_HANDLED (); /* sigsuspend handles our cancellation. */
-
-#ifndef NO_CANCELLATION
-# include <not-cancel.h>
-
-int
-__pause_nocancel (void)
-{
- sigset_t set;
-
- __sigemptyset (&set);
- __sigprocmask (SIG_BLOCK, NULL, &set);
-
- return sigsuspend_not_cancel (&set);
-}
-#endif
diff --git a/sysdeps/posix/posix_fallocate.c b/sysdeps/posix/posix_fallocate.c
index 970e7d80e8..f3c2182486 100644
--- a/sysdeps/posix/posix_fallocate.c
+++ b/sysdeps/posix/posix_fallocate.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000-2016 Free Software Foundation, Inc.
+/* Copyright (C) 2000-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/posix/posix_fallocate64.c b/sysdeps/posix/posix_fallocate64.c
index 0c094ff9b8..2eaeab2a6f 100644
--- a/sysdeps/posix/posix_fallocate64.c
+++ b/sysdeps/posix/posix_fallocate64.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000-2016 Free Software Foundation, Inc.
+/* Copyright (C) 2000-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/posix/pread.c b/sysdeps/posix/pread.c
index aa8e8901fd..aa0a56cf98 100644
--- a/sysdeps/posix/pread.c
+++ b/sysdeps/posix/pread.c
@@ -1,6 +1,6 @@
/* Read block from given position in file without changing file pointer.
POSIX version.
- Copyright (C) 1997-2016 Free Software Foundation, Inc.
+ Copyright (C) 1997-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
diff --git a/sysdeps/posix/pread64.c b/sysdeps/posix/pread64.c
index b7a2808c07..04146239a8 100644
--- a/sysdeps/posix/pread64.c
+++ b/sysdeps/posix/pread64.c
@@ -1,6 +1,6 @@
/* Read block from given position in file without changing file pointer.
POSIX version.
- Copyright (C) 1997-2016 Free Software Foundation, Inc.
+ Copyright (C) 1997-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
@@ -58,5 +58,6 @@ __libc_pread64 (int fd, void *buf, size_t nbyte, off64_t offset)
#ifndef __libc_pread64
weak_alias (__libc_pread64, __pread64)
+libc_hidden_weak (__pread64)
weak_alias (__libc_pread64, pread64)
#endif
diff --git a/sysdeps/posix/preadv.c b/sysdeps/posix/preadv.c
index fb7586c0a6..f944ec746e 100644
--- a/sysdeps/posix/preadv.c
+++ b/sysdeps/posix/preadv.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 2009-2016 Free Software Foundation, Inc.
+/* Read data into multiple buffers. Generic version.
+ Copyright (C) 2009-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -15,93 +16,15 @@
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
-#include <errno.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <limits.h>
-#include <stdbool.h>
-#include <sys/param.h>
-#if __WORDSIZE == 64 && !defined PREADV
-/* Hide the preadv64 declaration. */
-# define preadv64 __redirect_preadv64
-#endif
-#include <sys/uio.h>
-#include <bits/wordsize.h>
+#include <sys/types.h>
+
+#ifndef __OFF_T_MATCHES_OFF64_T
-#ifndef PREADV
# define PREADV preadv
# define PREAD __pread
# define OFF_T off_t
-#endif
-
-
-static void
-ifree (char **ptrp)
-{
- free (*ptrp);
-}
-
-
-/* Read data from file descriptor FD at the given position OFFSET
- without change the file pointer, and put the result in the buffers
- described by VECTOR, which is a vector of COUNT 'struct iovec's.
- The buffers are filled in the order specified. Operates just like
- 'pread' (see <unistd.h>) except that data are put in VECTOR instead
- of a contiguous buffer. */
-ssize_t
-PREADV (int fd, const struct iovec *vector, int count, OFF_T offset)
-{
- /* Find the total number of bytes to be read. */
- size_t bytes = 0;
- for (int i = 0; i < count; ++i)
- {
- /* Check for ssize_t overflow. */
- if (SSIZE_MAX - bytes < vector[i].iov_len)
- {
- __set_errno (EINVAL);
- return -1;
- }
- bytes += vector[i].iov_len;
- }
-
- /* Allocate a temporary buffer to hold the data. We should normally
- use alloca since it's faster and does not require synchronization
- with other threads. But we cannot if the amount of memory
- required is too large. */
- char *buffer;
- char *malloced_buffer __attribute__ ((__cleanup__ (ifree))) = NULL;
- if (__libc_use_alloca (bytes))
- buffer = (char *) __alloca (bytes);
- else
- {
- malloced_buffer = buffer = (char *) malloc (bytes);
- if (buffer == NULL)
- return -1;
- }
-
- /* Read the data. */
- ssize_t bytes_read = PREAD (fd, buffer, bytes, offset);
- if (bytes_read < 0)
- return -1;
-
- /* Copy the data from BUFFER into the memory specified by VECTOR. */
- bytes = bytes_read;
- for (int i = 0; i < count; ++i)
- {
- size_t copy = MIN (vector[i].iov_len, bytes);
-
- (void) memcpy ((void *) vector[i].iov_base, (void *) buffer, copy);
+# include <sysdeps/posix/preadv_common.c>
- buffer += copy;
- bytes -= copy;
- if (bytes == 0)
- break;
- }
+libc_hidden_def (preadv)
- return bytes_read;
-}
-#if __WORDSIZE == 64 && defined preadv64
-# undef preadv64
-strong_alias (preadv, preadv64)
#endif
diff --git a/sysdeps/posix/preadv2.c b/sysdeps/posix/preadv2.c
new file mode 100644
index 0000000000..4f8557ac83
--- /dev/null
+++ b/sysdeps/posix/preadv2.c
@@ -0,0 +1,42 @@
+/* Generic version of preadv2.
+ Copyright (C) 2017-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <sys/uio.h>
+
+#ifndef __OFF_T_MATCHES_OFF64_T
+
+/* Since we define no flags for preadv2 just route to preadv. */
+ssize_t
+preadv2 (int fd, const struct iovec *vector, int count, off_t offset,
+ int flags)
+{
+ if (flags != 0)
+ {
+ __set_errno (ENOTSUP);
+ return -1;
+ }
+
+ if (offset == -1)
+ return __readv (fd, vector, count);
+ else
+ return preadv (fd, vector, count, offset);
+}
+
+#endif
diff --git a/sysdeps/posix/preadv64.c b/sysdeps/posix/preadv64.c
index 198622353a..d0ee6dae4a 100644
--- a/sysdeps/posix/preadv64.c
+++ b/sysdeps/posix/preadv64.c
@@ -1,9 +1,28 @@
-#include <bits/wordsize.h>
+/* Read data into multiple buffers. Generic LFS version.
+ Copyright (C) 2009-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
-#if __WORDSIZE == 32
-# define PREADV preadv64
-# define PREAD __pread64
-# define OFF_T off64_t
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
-# include "preadv.c"
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#define PREADV preadv64
+#define PREAD __pread64
+#define OFF_T off64_t
+#include <sysdeps/posix/preadv_common.c>
+
+libc_hidden_def (preadv64)
+#ifdef __OFF_T_MATCHES_OFF64_T
+strong_alias (preadv64, preadv)
+libc_hidden_def (preadv)
#endif
diff --git a/sysdeps/posix/preadv64v2.c b/sysdeps/posix/preadv64v2.c
new file mode 100644
index 0000000000..f89ad08c54
--- /dev/null
+++ b/sysdeps/posix/preadv64v2.c
@@ -0,0 +1,41 @@
+/* Generic version of preadv2.
+ Copyright (C) 2017-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <sys/uio.h>
+
+ssize_t
+preadv64v2 (int fd, const struct iovec *vector, int count, off64_t offset,
+ int flags)
+{
+ if (flags != 0)
+ {
+ __set_errno (ENOTSUP);
+ return -1;
+ }
+
+ if (offset == -1)
+ return __readv (fd, vector, count);
+ else
+ return preadv64 (fd, vector, count, offset);
+}
+
+#ifdef __OFF_T_MATCHES_OFF64_T
+strong_alias (preadv64v2, preadv2)
+#endif
diff --git a/sysdeps/posix/preadv_common.c b/sysdeps/posix/preadv_common.c
new file mode 100644
index 0000000000..14fd4cea2a
--- /dev/null
+++ b/sysdeps/posix/preadv_common.c
@@ -0,0 +1,85 @@
+/* Read data into multiple buffers. Base implementation for preadv
+ and preadv64.
+ Copyright (C) 2017-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <unistd.h>
+#include <sys/uio.h>
+#include <sys/param.h>
+#include <errno.h>
+#include <malloc.h>
+
+#include <ldsodefs.h>
+#include <libc-pointer-arith.h>
+
+/* Read data from file descriptor FD at the given position OFFSET
+ without change the file pointer, and put the result in the buffers
+ described by VECTOR, which is a vector of COUNT 'struct iovec's.
+ The buffers are filled in the order specified. Operates just like
+ 'pread' (see <unistd.h>) except that data are put in VECTOR instead
+ of a contiguous buffer. */
+ssize_t
+PREADV (int fd, const struct iovec *vector, int count, OFF_T offset)
+{
+ /* Find the total number of bytes to be read. */
+ size_t bytes = 0;
+ for (int i = 0; i < count; ++i)
+ {
+ /* Check for ssize_t overflow. */
+ if (SSIZE_MAX - bytes < vector[i].iov_len)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+ bytes += vector[i].iov_len;
+ }
+
+ /* Allocate a temporary buffer to hold the data. It could be done with a
+ stack allocation, but due limitations on some system (Linux with
+ O_DIRECT) it aligns the buffer to pagesize. A possible optimization
+ would be querying if the syscall would impose any alignment constraint,
+ but 1. it is system specific (not meant in generic implementation), and
+ 2. it would make the implementation more complex, and 3. it will require
+ another syscall (fcntl). */
+ void *buffer = __mmap (NULL, bytes, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ if (__glibc_unlikely (buffer == MAP_FAILED))
+ return -1;
+
+ ssize_t bytes_read = PREAD (fd, buffer, bytes, offset);
+ if (bytes_read < 0)
+ goto end;
+
+ /* Copy the data from BUFFER into the memory specified by VECTOR. */
+ bytes = bytes_read;
+ void *buf = buffer;
+ for (int i = 0; i < count; ++i)
+ {
+ size_t copy = MIN (vector[i].iov_len, bytes);
+
+ memcpy (vector[i].iov_base, buf, copy);
+
+ buf += copy;
+ bytes -= copy;
+ if (bytes == 0)
+ break;
+ }
+
+end:
+ __munmap (buffer, bytes);
+ return bytes_read;
+}
diff --git a/sysdeps/posix/profil.c b/sysdeps/posix/profil.c
index 23e601c6c2..ae0a663533 100644
--- a/sysdeps/posix/profil.c
+++ b/sysdeps/posix/profil.c
@@ -1,5 +1,5 @@
/* Low-level statistical profiling support function. Mostly POSIX.1 version.
- Copyright (C) 1996-2016 Free Software Foundation, Inc.
+ Copyright (C) 1996-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -22,6 +22,7 @@
#include <signal.h>
#include <sys/time.h>
#include <libc-internal.h>
+#include <sigsetops.h>
#ifndef SIGPROF
diff --git a/sysdeps/posix/pwrite.c b/sysdeps/posix/pwrite.c
index c3aa7c084a..0455a806d0 100644
--- a/sysdeps/posix/pwrite.c
+++ b/sysdeps/posix/pwrite.c
@@ -1,6 +1,6 @@
/* Write block to given position in file without changing file pointer.
POSIX version.
- Copyright (C) 1997-2016 Free Software Foundation, Inc.
+ Copyright (C) 1997-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
diff --git a/sysdeps/posix/pwrite64.c b/sysdeps/posix/pwrite64.c
index 721c733c3f..38c1903958 100644
--- a/sysdeps/posix/pwrite64.c
+++ b/sysdeps/posix/pwrite64.c
@@ -1,6 +1,6 @@
/* Write block to given position in file without changing file pointer.
POSIX version.
- Copyright (C) 1997-2016 Free Software Foundation, Inc.
+ Copyright (C) 1997-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
diff --git a/sysdeps/posix/pwritev.c b/sysdeps/posix/pwritev.c
index 8c483f1b47..3a8b1b2081 100644
--- a/sysdeps/posix/pwritev.c
+++ b/sysdeps/posix/pwritev.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 2009-2016 Free Software Foundation, Inc.
+/* Write data into multiple buffers. Generic version.
+ Copyright (C) 2009-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -15,81 +16,15 @@
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
-#include <errno.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <limits.h>
-#include <stdbool.h>
-#include <sys/param.h>
-#if __WORDSIZE == 64 && !defined PWRITEV
-/* Hide the pwritev64 declaration. */
-# define pwritev64 __redirect_pwritev64
-#endif
-#include <sys/uio.h>
-#include <bits/wordsize.h>
+#include <sys/types.h>
+
+#ifndef __OFF_T_MATCHES_OFF64_T
-#ifndef PWRITEV
# define PWRITEV pwritev
# define PWRITE __pwrite
# define OFF_T off_t
-#endif
-
-
-static void
-ifree (char **ptrp)
-{
- free (*ptrp);
-}
-
-
-/* Write data pointed by the buffers described by IOVEC, which is a
- vector of COUNT 'struct iovec's, to file descriptor FD at the given
- position OFFSET without change the file pointer. The data is
- written in the order specified. Operates just like 'write' (see
- <unistd.h>) except that the data are taken from IOVEC instead of a
- contiguous buffer. */
-ssize_t
-PWRITEV (int fd, const struct iovec *vector, int count, OFF_T offset)
-{
- /* Find the total number of bytes to be read. */
- size_t bytes = 0;
- for (int i = 0; i < count; ++i)
- {
- /* Check for ssize_t overflow. */
- if (SSIZE_MAX - bytes < vector[i].iov_len)
- {
- __set_errno (EINVAL);
- return -1;
- }
- bytes += vector[i].iov_len;
- }
-
- /* Allocate a temporary buffer to hold the data. We should normally
- use alloca since it's faster and does not require synchronization
- with other threads. But we cannot if the amount of memory
- required is too large. */
- char *buffer;
- char *malloced_buffer __attribute__ ((__cleanup__ (ifree))) = NULL;
- if (__libc_use_alloca (bytes))
- buffer = (char *) __alloca (bytes);
- else
- {
- malloced_buffer = buffer = (char *) malloc (bytes);
- if (buffer == NULL)
- return -1;
- }
+# include <sysdeps/posix/pwritev_common.c>
- /* Copy the data from BUFFER into the memory specified by VECTOR. */
- char *ptr = buffer;
- for (int i = 0; i < count; ++i)
- ptr = __mempcpy ((void *) ptr, (void *) vector[i].iov_base,
- vector[i].iov_len);
+libc_hidden_def (pwritev)
- /* Write the data. */
- return PWRITE (fd, buffer, bytes, offset);
-}
-#if __WORDSIZE == 64 && defined pwritev64
-# undef pwritev64
-strong_alias (pwritev, pwritev64)
#endif
diff --git a/sysdeps/posix/pwritev2.c b/sysdeps/posix/pwritev2.c
new file mode 100644
index 0000000000..a39304d9d9
--- /dev/null
+++ b/sysdeps/posix/pwritev2.c
@@ -0,0 +1,42 @@
+/* Generic version of pwritev2.
+ Copyright (C) 2017-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <sys/uio.h>
+
+#ifndef __OFF_T_MATCHES_OFF64_T
+
+/* Since we define no flags for pwritev2 just route to pwritev. */
+ssize_t
+pwritev2 (int fd, const struct iovec *vector, int count, off_t offset,
+ int flags)
+{
+ if (flags != 0)
+ {
+ __set_errno (ENOTSUP);
+ return -1;
+ }
+
+ if (offset == -1)
+ return __writev (fd, vector, count);
+ else
+ return pwritev (fd, vector, count, offset);
+}
+
+#endif
diff --git a/sysdeps/posix/pwritev64.c b/sysdeps/posix/pwritev64.c
index 4948d2efee..f16b1c1b8e 100644
--- a/sysdeps/posix/pwritev64.c
+++ b/sysdeps/posix/pwritev64.c
@@ -1,9 +1,28 @@
-#include <bits/wordsize.h>
+/* Write data into multiple buffers. Generic LFS version.
+ Copyright (C) 2009-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
-#if __WORDSIZE == 32
-# define PWRITEV pwritev64
-# define PWRITE __pwrite64
-# define OFF_T off64_t
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
-# include "pwritev.c"
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#define PWRITEV pwritev64
+#define PWRITE __pwrite64
+#define OFF_T off64_t
+#include <sysdeps/posix/pwritev_common.c>
+
+libc_hidden_def (pwritev64)
+#ifdef __OFF_T_MATCHES_OFF64_T
+strong_alias (pwritev64, pwritev)
+libc_hidden_def (pwritev)
#endif
diff --git a/sysdeps/posix/pwritev64v2.c b/sysdeps/posix/pwritev64v2.c
new file mode 100644
index 0000000000..7a3a3239d7
--- /dev/null
+++ b/sysdeps/posix/pwritev64v2.c
@@ -0,0 +1,42 @@
+/* Generic version of pwritev2.
+ Copyright (C) 2017-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <sys/uio.h>
+
+/* Since we define no flags for pwritev2 just route to pwritev. */
+ssize_t
+pwritev64v2 (int fd, const struct iovec *vector, int count, off64_t offset,
+ int flags)
+{
+ if (flags != 0)
+ {
+ __set_errno (ENOTSUP);
+ return -1;
+ }
+
+ if (offset == -1)
+ return __writev (fd, vector, count);
+ else
+ return pwritev64 (fd, vector, count, offset);
+}
+
+#ifdef __OFF_T_MATCHES_OFF64_T
+strong_alias (pwritev64v2, pwritev2)
+#endif
diff --git a/sysdeps/posix/pwritev_common.c b/sysdeps/posix/pwritev_common.c
new file mode 100644
index 0000000000..344ab4d61b
--- /dev/null
+++ b/sysdeps/posix/pwritev_common.c
@@ -0,0 +1,74 @@
+/* Write data into multiple buffers. Base implementation for pwritev
+ and pwritev64.
+ Copyright (C) 2017-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <unistd.h>
+#include <sys/uio.h>
+#include <sys/param.h>
+#include <errno.h>
+#include <malloc.h>
+
+#include <ldsodefs.h>
+#include <libc-pointer-arith.h>
+
+/* Write data pointed by the buffers described by IOVEC, which is a
+ vector of COUNT 'struct iovec's, to file descriptor FD at the given
+ position OFFSET without change the file pointer. The data is
+ written in the order specified. Operates just like 'write' (see
+ <unistd.h>) except that the data are taken from IOVEC instead of a
+ contiguous buffer. */
+ssize_t
+PWRITEV (int fd, const struct iovec *vector, int count, OFF_T offset)
+{
+ /* Find the total number of bytes to be read. */
+ size_t bytes = 0;
+ for (int i = 0; i < count; ++i)
+ {
+ /* Check for ssize_t overflow. */
+ if (SSIZE_MAX - bytes < vector[i].iov_len)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+ bytes += vector[i].iov_len;
+ }
+
+ /* Allocate a temporary buffer to hold the data. It could be done with a
+ stack allocation, but due limitations on some system (Linux with
+ O_DIRECT) it aligns the buffer to pagesize. A possible optimization
+ would be querying if the syscall would impose any alignment constraint,
+ but 1. it is system specific (not meant in generic implementation), and
+ 2. it would make the implementation more complex, and 3. it will require
+ another syscall (fcntl). */
+ void *buffer = __mmap (NULL, bytes, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ if (__glibc_unlikely (buffer == MAP_FAILED))
+ return -1;
+
+ /* Copy the data from BUFFER into the memory specified by VECTOR. */
+ char *ptr = buffer;
+ for (int i = 0; i < count; ++i)
+ ptr = __mempcpy ((void *) ptr, (void *) vector[i].iov_base,
+ vector[i].iov_len);
+
+ ssize_t ret = PWRITE (fd, buffer, bytes, offset);
+
+ __munmap (buffer, bytes);
+
+ return ret;
+}
diff --git a/sysdeps/posix/raise.c b/sysdeps/posix/raise.c
index d438fcb87e..1f02b201e1 100644
--- a/sysdeps/posix/raise.c
+++ b/sysdeps/posix/raise.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/posix/readdir.c b/sysdeps/posix/readdir.c
index e1e63f6157..a6ecc0fe5b 100644
--- a/sysdeps/posix/readdir.c
+++ b/sysdeps/posix/readdir.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -120,3 +120,8 @@ __READDIR (DIR *dirp)
#ifdef __READDIR_ALIAS
weak_alias (__readdir, readdir)
#endif
+
+#undef __READDIR
+#undef __GETDENTS
+#undef DIRENT_TYPE
+#undef __READDIR_ALIAS
diff --git a/sysdeps/posix/readdir_r.c b/sysdeps/posix/readdir_r.c
index 4c7b3701fe..2d691e7242 100644
--- a/sysdeps/posix/readdir_r.c
+++ b/sysdeps/posix/readdir_r.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -152,3 +152,8 @@ __READDIR_R (DIR *dirp, DIRENT_TYPE *entry, DIRENT_TYPE **result)
#ifdef __READDIR_R_ALIAS
weak_alias (__readdir_r, readdir_r)
#endif
+
+#undef __READDIR_R
+#undef __GETDENTS
+#undef DIRENT_TYPE
+#undef __READDIR_R_ALIAS
diff --git a/sysdeps/posix/readv.c b/sysdeps/posix/readv.c
index 17a864d2fa..4fe6218454 100644
--- a/sysdeps/posix/readv.c
+++ b/sysdeps/posix/readv.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -88,4 +88,5 @@ __readv (int fd, const struct iovec *vector, int count)
return bytes_read;
}
+libc_hidden_def (__readv)
weak_alias (__readv, readv)
diff --git a/sysdeps/posix/remove.c b/sysdeps/posix/remove.c
index 8d331fa171..1ddf9ebc1b 100644
--- a/sysdeps/posix/remove.c
+++ b/sysdeps/posix/remove.c
@@ -1,5 +1,5 @@
/* ANSI C `remove' function to delete a file or directory. POSIX.1 version.
- Copyright (C) 1995-2016 Free Software Foundation, Inc.
+ Copyright (C) 1995-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/posix/rename.c b/sysdeps/posix/rename.c
index df34f0949d..15c7f56e65 100644
--- a/sysdeps/posix/rename.c
+++ b/sysdeps/posix/rename.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/posix/rewinddir.c b/sysdeps/posix/rewinddir.c
index 1fa4c94a04..5c5d8f1514 100644
--- a/sysdeps/posix/rewinddir.c
+++ b/sysdeps/posix/rewinddir.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/posix/seekdir.c b/sysdeps/posix/seekdir.c
index 5e774a16e8..bcf2405e16 100644
--- a/sysdeps/posix/seekdir.c
+++ b/sysdeps/posix/seekdir.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/posix/shm-directory.c b/sysdeps/posix/shm-directory.c
index 953085b7ce..4e2285ff24 100644
--- a/sysdeps/posix/shm-directory.c
+++ b/sysdeps/posix/shm-directory.c
@@ -1,5 +1,5 @@
/* Determine directory for shm/sem files. Generic POSIX version.
- Copyright (C) 2014-2016 Free Software Foundation, Inc.
+ Copyright (C) 2014-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/posix/shm-directory.h b/sysdeps/posix/shm-directory.h
index 76c528d8be..55ded84efa 100644
--- a/sysdeps/posix/shm-directory.h
+++ b/sysdeps/posix/shm-directory.h
@@ -1,5 +1,5 @@
/* Header for directory for shm/sem files.
- Copyright (C) 2014-2016 Free Software Foundation, Inc.
+ Copyright (C) 2014-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/posix/shm_open.c b/sysdeps/posix/shm_open.c
index f2961620b4..b9b473ceed 100644
--- a/sysdeps/posix/shm_open.c
+++ b/sysdeps/posix/shm_open.c
@@ -1,5 +1,5 @@
/* shm_open -- open a POSIX shared memory object. Generic POSIX file version.
- Copyright (C) 2001-2016 Free Software Foundation, Inc.
+ Copyright (C) 2001-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -25,6 +25,7 @@
#else
# include <fcntl.h>
+# include <pthread.h>
# include <shm-directory.h>
@@ -34,12 +35,12 @@ shm_open (const char *name, int oflag, mode_t mode)
{
SHM_GET_NAME (EINVAL, -1, "");
-# ifdef O_NOFOLLOW
- oflag |= O_NOFOLLOW;
-# endif
-# ifdef O_CLOEXEC
- oflag |= O_CLOEXEC;
-# endif
+ oflag |= O_NOFOLLOW | O_CLOEXEC;
+
+ /* Disable asynchronous cancellation. */
+ int state;
+ pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &state);
+
int fd = open (shm_name, oflag, mode);
if (fd == -1 && __glibc_unlikely (errno == EISDIR))
/* It might be better to fold this error with EINVAL since
@@ -47,28 +48,7 @@ shm_open (const char *name, int oflag, mode_t mode)
object names and the standard does not mention EISDIR. */
__set_errno (EINVAL);
-# ifndef O_CLOEXEC
- if (fd != -1)
- {
- /* We got a descriptor. Now set the FD_CLOEXEC bit. */
- int flags = fcntl (fd, F_GETFD, 0);
-
- if (__glibc_likely (flags != -1))
- {
- flags |= FD_CLOEXEC;
- flags = fcntl (fd, F_SETFD, flags);
- }
-
- if (flags == -1)
- {
- /* Something went wrong. We cannot return the descriptor. */
- int save_errno = errno;
- close (fd);
- fd = -1;
- __set_errno (save_errno);
- }
- }
-# endif
+ pthread_setcancelstate (state, NULL);
return fd;
}
diff --git a/sysdeps/posix/shm_unlink.c b/sysdeps/posix/shm_unlink.c
index ae742d3fcb..de8466f4c1 100644
--- a/sysdeps/posix/shm_unlink.c
+++ b/sysdeps/posix/shm_unlink.c
@@ -1,5 +1,5 @@
/* shm_unlink -- remove a POSIX shared memory object. Generic POSIX version.
- Copyright (C) 2001-2016 Free Software Foundation, Inc.
+ Copyright (C) 2001-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/posix/sigblock.c b/sysdeps/posix/sigblock.c
index c28b819376..9d8f4db47d 100644
--- a/sysdeps/posix/sigblock.c
+++ b/sysdeps/posix/sigblock.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -35,4 +35,5 @@ __sigblock (int mask)
return sigset_get_old_mask (&oset);
}
+libc_hidden_def (__sigblock)
weak_alias (__sigblock, sigblock)
diff --git a/sysdeps/posix/sigignore.c b/sysdeps/posix/sigignore.c
index 28d3eeb706..120d06cef1 100644
--- a/sysdeps/posix/sigignore.c
+++ b/sysdeps/posix/sigignore.c
@@ -1,5 +1,5 @@
/* Set the disposition of SIG to SIG_IGN.
- Copyright (C) 1998-2016 Free Software Foundation, Inc.
+ Copyright (C) 1998-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
@@ -22,7 +22,7 @@
#include <stddef.h>
#include <signal.h>
#include <string.h> /* For the real memset prototype. */
-
+#include <sigsetops.h>
int
sigignore (int sig)
@@ -30,8 +30,7 @@ sigignore (int sig)
struct sigaction act;
act.sa_handler = SIG_IGN;
- if (__sigemptyset (&act.sa_mask) < 0)
- return -1;
+ __sigemptyset (&act.sa_mask);
act.sa_flags = 0;
return __sigaction (sig, &act, NULL);
diff --git a/sysdeps/posix/sigintr.c b/sysdeps/posix/sigintr.c
index bce75b7cf9..435fc75f3e 100644
--- a/sysdeps/posix/sigintr.c
+++ b/sysdeps/posix/sigintr.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1992-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -18,6 +18,7 @@
#include <stddef.h>
#include <signal.h>
#include <errno.h>
+#include <sigsetops.h>
/* If INTERRUPT is nonzero, make signal SIG interrupt system calls
(causing them to fail with EINTR); if INTERRUPT is zero, make system
diff --git a/sysdeps/posix/signal.c b/sysdeps/posix/signal.c
index 6884fc742d..8a135c7b0e 100644
--- a/sysdeps/posix/signal.c
+++ b/sysdeps/posix/signal.c
@@ -1,5 +1,5 @@
/* BSD-like signal function.
- Copyright (C) 1991-2016 Free Software Foundation, Inc.
+ Copyright (C) 1991-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -18,8 +18,8 @@
#include <errno.h>
#include <signal.h>
-#include <string.h> /* For the real memset prototype. */
-
+#include <sigsetops.h>
+#include <internal-signals.h>
sigset_t _sigintr attribute_hidden; /* Set by siginterrupt. */
@@ -31,16 +31,16 @@ __bsd_signal (int sig, __sighandler_t handler)
struct sigaction act, oact;
/* Check signal extents to protect __sigismember. */
- if (handler == SIG_ERR || sig < 1 || sig >= NSIG)
+ if (handler == SIG_ERR || sig < 1 || sig >= NSIG
+ || __is_internal_signal (sig))
{
__set_errno (EINVAL);
return SIG_ERR;
}
act.sa_handler = handler;
- if (__sigemptyset (&act.sa_mask) < 0
- || __sigaddset (&act.sa_mask, sig) < 0)
- return SIG_ERR;
+ __sigemptyset (&act.sa_mask);
+ __sigaddset (&act.sa_mask, sig);
act.sa_flags = __sigismember (&_sigintr, sig) ? 0 : SA_RESTART;
if (__sigaction (sig, &act, &oact) < 0)
return SIG_ERR;
diff --git a/sysdeps/posix/sigpause.c b/sysdeps/posix/sigpause.c
index bbe8bde324..db9df8eb6e 100644
--- a/sysdeps/posix/sigpause.c
+++ b/sysdeps/posix/sigpause.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -19,15 +19,13 @@
#include <errno.h>
#include <signal.h>
#include <stddef.h> /* For NULL. */
-#include <sysdep-cancel.h>
#undef sigpause
#include <sigset-cvt-mask.h>
+#include <sysdep-cancel.h>
-/* Set the mask of blocked signals to MASK,
- wait for a signal to arrive, and then restore the mask. */
-static int
-do_sigpause (int sig_or_mask, int is_sig)
+int
+__sigpause (int sig_or_mask, int is_sig)
{
sigset_t set;
@@ -46,21 +44,6 @@ do_sigpause (int sig_or_mask, int is_sig)
to do anything here. */
return __sigsuspend (&set);
}
-
-int
-__sigpause (int sig_or_mask, int is_sig)
-{
- if (SINGLE_THREAD_P)
- return do_sigpause (sig_or_mask, is_sig);
-
- int oldtype = LIBC_CANCEL_ASYNC ();
-
- int result = do_sigpause (sig_or_mask, is_sig);
-
- LIBC_CANCEL_RESET (oldtype);
-
- return result;
-}
libc_hidden_def (__sigpause)
/* We have to provide a default version of this function since the
@@ -87,3 +70,6 @@ __xpg_sigpause (int sig)
return __sigpause (sig, 1);
}
strong_alias (__xpg_sigpause, __libc___xpg_sigpause)
+
+/* __sigsuspend handles cancellation. */
+LIBC_CANCEL_HANDLED ();
diff --git a/sysdeps/posix/sigset.c b/sysdeps/posix/sigset.c
index 765fe637f1..6ab4a48767 100644
--- a/sysdeps/posix/sigset.c
+++ b/sysdeps/posix/sigset.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1998-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -8,7 +8,7 @@
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
@@ -20,7 +20,7 @@
#include <stddef.h>
#include <signal.h>
#include <string.h> /* For the real memset prototype. */
-
+#include <sigsetops.h>
/* Set the disposition for SIG. */
__sighandler_t
@@ -31,19 +31,13 @@ sigset (int sig, __sighandler_t disp)
sigset_t set;
sigset_t oset;
-#ifdef SIG_HOLD
- /* Handle SIG_HOLD first. */
+ __sigemptyset (&set);
+ if (sigaddset (&set, sig) < 0)
+ return SIG_ERR;
+
if (disp == SIG_HOLD)
{
- /* Create an empty signal set. */
- if (__sigemptyset (&set) < 0)
- return SIG_ERR;
-
- /* Add the specified signal. */
- if (__sigaddset (&set, sig) < 0)
- return SIG_ERR;
-
- /* Add the signal set to the current signal mask. */
+ /* Add the signal to the current signal mask. */
if (__sigprocmask (SIG_BLOCK, &set, &oset) < 0)
return SIG_ERR;
@@ -57,34 +51,19 @@ sigset (int sig, __sighandler_t disp)
return oact.sa_handler;
}
-#endif /* SIG_HOLD */
-
- /* Check signal extents to protect __sigismember. */
- if (disp == SIG_ERR || sig < 1 || sig >= NSIG)
+ else
{
- __set_errno (EINVAL);
- return SIG_ERR;
- }
-
- act.sa_handler = disp;
- if (__sigemptyset (&act.sa_mask) < 0)
- return SIG_ERR;
- act.sa_flags = 0;
- if (__sigaction (sig, &act, &oact) < 0)
- return SIG_ERR;
-
- /* Create an empty signal set. */
- if (__sigemptyset (&set) < 0)
- return SIG_ERR;
-
- /* Add the specified signal. */
- if (__sigaddset (&set, sig) < 0)
- return SIG_ERR;
+ act.sa_handler = disp;
+ __sigemptyset (&act.sa_mask);
+ act.sa_flags = 0;
+ if (__sigaction (sig, &act, &oact) < 0)
+ return SIG_ERR;
- /* Remove the signal set from the current signal mask. */
- if (__sigprocmask (SIG_UNBLOCK, &set, &oset) < 0)
- return SIG_ERR;
+ /* Remove the signal from the current signal mask. */
+ if (__sigprocmask (SIG_UNBLOCK, &set, &oset) < 0)
+ return SIG_ERR;
- /* If the signal was already blocked return SIG_HOLD. */
- return __sigismember (&oset, sig) ? SIG_HOLD : oact.sa_handler;
+ /* If the signal was already blocked return SIG_HOLD. */
+ return __sigismember (&oset, sig) ? SIG_HOLD : oact.sa_handler;
+ }
}
diff --git a/sysdeps/posix/sigsetmask.c b/sysdeps/posix/sigsetmask.c
index bb16262ece..9895848937 100644
--- a/sysdeps/posix/sigsetmask.c
+++ b/sysdeps/posix/sigsetmask.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/posix/sigsuspend.c b/sysdeps/posix/sigsuspend.c
index 090edc208c..50953fc818 100644
--- a/sysdeps/posix/sigsuspend.c
+++ b/sysdeps/posix/sigsuspend.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/posix/sigwait.c b/sysdeps/posix/sigwait.c
index b9b328176d..4ff9d847d4 100644
--- a/sysdeps/posix/sigwait.c
+++ b/sysdeps/posix/sigwait.c
@@ -1,5 +1,5 @@
/* Implementation of sigwait function from POSIX.1c.
- Copyright (C) 1996-2016 Free Software Foundation, Inc.
+ Copyright (C) 1996-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
diff --git a/sysdeps/posix/sleep.c b/sysdeps/posix/sleep.c
index f15028bd1a..7de748fe44 100644
--- a/sysdeps/posix/sleep.c
+++ b/sysdeps/posix/sleep.c
@@ -1,5 +1,5 @@
/* Sleep for a given number of seconds. POSIX.1 version.
- Copyright (C) 1991-2016 Free Software Foundation, Inc.
+ Copyright (C) 1991-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/posix/spawni.c b/sysdeps/posix/spawni.c
index 043266dcd3..b138ab4393 100644
--- a/sysdeps/posix/spawni.c
+++ b/sysdeps/posix/spawni.c
@@ -1,5 +1,5 @@
/* Guts of POSIX spawn interface. Generic POSIX.1 version.
- Copyright (C) 2000-2016 Free Software Foundation, Inc.
+ Copyright (C) 2000-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -16,20 +16,23 @@
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
-#include <errno.h>
+#include <spawn.h>
+#include <assert.h>
#include <fcntl.h>
#include <paths.h>
-#include <spawn.h>
-#include <stdbool.h>
-#include <stdlib.h>
#include <string.h>
-#include <unistd.h>
-#include <signal.h>
#include <sys/resource.h>
-#include "spawn_int.h"
+#include <sys/wait.h>
+#include <sys/param.h>
+#include <sys/mman.h>
#include <not-cancel.h>
#include <local-setxid.h>
#include <shlib-compat.h>
+#include <nptl/pthreadP.h>
+#include <dl-sysdep.h>
+#include <libc-pointer-arith.h>
+#include <ldsodefs.h>
+#include "spawn_int.h"
/* The Unix standard contains a long explanation of the way to signal
@@ -39,93 +42,59 @@
normal program exit with the exit code 127. */
#define SPAWN_ERROR 127
-
-/* The file is accessible but it is not an executable file. Invoke
- the shell to interpret it as a script. */
-static void
-internal_function
-script_execute (const char *file, char *const argv[], char *const envp[])
+struct posix_spawn_args
{
- /* Count the arguments. */
- int argc = 0;
- while (argv[argc++])
- ;
-
- /* Construct an argument list for the shell. */
- {
- char *new_argv[argc + 1];
- new_argv[0] = (char *) _PATH_BSHELL;
- new_argv[1] = (char *) file;
- while (argc > 1)
- {
- new_argv[argc] = argv[argc - 1];
- --argc;
- }
-
- /* Execute the shell. */
- __execve (new_argv[0], new_argv, envp);
- }
-}
-
-static inline void
-maybe_script_execute (const char *file, char *const argv[], char *const envp[],
- int xflags)
+ sigset_t oldmask;
+ const char *file;
+ int (*exec) (const char *, char *const *, char *const *);
+ const posix_spawn_file_actions_t *fa;
+ const posix_spawnattr_t *restrict attr;
+ char *const *argv;
+ ptrdiff_t argc;
+ char *const *envp;
+ int xflags;
+ int pipe[2];
+};
+
+/* Older version requires that shell script without shebang definition
+ to be called explicitly using /bin/sh (_PATH_BSHELL). */
+static void
+maybe_script_execute (struct posix_spawn_args *args)
{
if (SHLIB_COMPAT (libc, GLIBC_2_2, GLIBC_2_15)
- && (xflags & SPAWN_XFLAGS_TRY_SHELL)
- && errno == ENOEXEC)
- script_execute (file, argv, envp);
-}
-
-/* Spawn a new process executing PATH with the attributes describes in *ATTRP.
- Before running the process perform the actions described in FILE-ACTIONS. */
-int
-__spawni (pid_t *pid, const char *file,
- const posix_spawn_file_actions_t *file_actions,
- const posix_spawnattr_t *attrp, char *const argv[],
- char *const envp[], int xflags)
-{
- pid_t new_pid;
- char *path, *p, *name;
- size_t len;
- size_t pathlen;
-
- /* Do this once. */
- short int flags = attrp == NULL ? 0 : attrp->__flags;
-
- /* Generate the new process. */
- if ((flags & POSIX_SPAWN_USEVFORK) != 0
- /* If no major work is done, allow using vfork. Note that we
- might perform the path searching. But this would be done by
- a call to execvp(), too, and such a call must be OK according
- to POSIX. */
- || ((flags & (POSIX_SPAWN_SETSIGMASK | POSIX_SPAWN_SETSIGDEF
- | POSIX_SPAWN_SETSCHEDPARAM | POSIX_SPAWN_SETSCHEDULER
- | POSIX_SPAWN_SETPGROUP | POSIX_SPAWN_RESETIDS)) == 0
- && file_actions == NULL))
- new_pid = __vfork ();
- else
- new_pid = __fork ();
-
- if (new_pid != 0)
+ && (args->xflags & SPAWN_XFLAGS_TRY_SHELL) && errno == ENOEXEC)
{
- if (new_pid < 0)
- return errno;
-
- /* The call was successful. Store the PID if necessary. */
- if (pid != NULL)
- *pid = new_pid;
+ char *const *argv = args->argv;
+ ptrdiff_t argc = args->argc;
+
+ /* Construct an argument list for the shell. */
+ char *new_argv[argc + 1];
+ new_argv[0] = (char *) _PATH_BSHELL;
+ new_argv[1] = (char *) args->file;
+ if (argc > 1)
+ memcpy (new_argv + 2, argv + 1, argc * sizeof(char *));
+ else
+ new_argv[2] = NULL;
- return 0;
+ /* Execute the shell. */
+ args->exec (new_argv[0], new_argv, args->envp);
}
+}
- /* Set signal mask. */
- if ((flags & POSIX_SPAWN_SETSIGMASK) != 0
- && __sigprocmask (SIG_SETMASK, &attrp->__ss, NULL) != 0)
- _exit (SPAWN_ERROR);
+/* Function used in the clone call to setup the signals mask, posix_spawn
+ attributes, and file actions. */
+static int
+__spawni_child (void *arguments)
+{
+ struct posix_spawn_args *args = arguments;
+ const posix_spawnattr_t *restrict attr = args->attr;
+ const posix_spawn_file_actions_t *file_actions = args->fa;
+ int ret;
+
+ __close (args->pipe[0]);
/* Set signal default action. */
- if ((flags & POSIX_SPAWN_SETSIGDEF) != 0)
+ if ((attr->__flags & POSIX_SPAWN_SETSIGDEF) != 0)
{
/* We have to iterate over all signals. This could possibly be
done better but it requires system specific solutions since
@@ -138,37 +107,41 @@ __spawni (pid_t *pid, const char *file,
sa.sa_handler = SIG_DFL;
for (sig = 1; sig <= _NSIG; ++sig)
- if (__sigismember (&attrp->__sd, sig) != 0
+ if (__sigismember (&attr->__sd, sig) != 0
&& __sigaction (sig, &sa, NULL) != 0)
- _exit (SPAWN_ERROR);
-
+ goto fail;
}
#ifdef _POSIX_PRIORITY_SCHEDULING
/* Set the scheduling algorithm and parameters. */
- if ((flags & (POSIX_SPAWN_SETSCHEDPARAM | POSIX_SPAWN_SETSCHEDULER))
+ if ((attr->__flags & (POSIX_SPAWN_SETSCHEDPARAM | POSIX_SPAWN_SETSCHEDULER))
== POSIX_SPAWN_SETSCHEDPARAM)
{
- if (__sched_setparam (0, &attrp->__sp) == -1)
- _exit (SPAWN_ERROR);
+ if (__sched_setparam (0, &attr->__sp) == -1)
+ goto fail;
}
- else if ((flags & POSIX_SPAWN_SETSCHEDULER) != 0)
+ else if ((attr->__flags & POSIX_SPAWN_SETSCHEDULER) != 0)
{
- if (__sched_setscheduler (0, attrp->__policy, &attrp->__sp) == -1)
- _exit (SPAWN_ERROR);
+ if (__sched_setscheduler (0, attr->__policy, &attr->__sp) == -1)
+ goto fail;
}
#endif
+ /* Set the process session ID. */
+ if ((attr->__flags & POSIX_SPAWN_SETSID) != 0
+ && __setsid () < 0)
+ goto fail;
+
/* Set the process group ID. */
- if ((flags & POSIX_SPAWN_SETPGROUP) != 0
- && __setpgid (0, attrp->__pgrp) != 0)
- _exit (SPAWN_ERROR);
+ if ((attr->__flags & POSIX_SPAWN_SETPGROUP) != 0
+ && __setpgid (0, attr->__pgrp) != 0)
+ goto fail;
/* Set the effective user and group IDs. */
- if ((flags & POSIX_SPAWN_RESETIDS) != 0
+ if ((attr->__flags & POSIX_SPAWN_RESETIDS) != 0
&& (local_seteuid (__getuid ()) != 0
- || local_setegid (__getgid ()) != 0))
- _exit (SPAWN_ERROR);
+ || local_setegid (__getgid ())) != 0)
+ goto fail;
/* Execute the file actions. */
if (file_actions != NULL)
@@ -184,9 +157,9 @@ __spawni (pid_t *pid, const char *file,
switch (action->tag)
{
case spawn_do_close:
- if (close_not_cancel (action->action.close_action.fd) != 0)
+ if (__close_nocancel (action->action.close_action.fd) != 0)
{
- if (! have_fdlimit)
+ if (have_fdlimit == 0)
{
__getrlimit64 (RLIMIT_NOFILE, &fdlimit);
have_fdlimit = true;
@@ -195,33 +168,37 @@ __spawni (pid_t *pid, const char *file,
/* Only signal errors for file descriptors out of range. */
if (action->action.close_action.fd < 0
|| action->action.close_action.fd >= fdlimit.rlim_cur)
- /* Signal the error. */
- _exit (SPAWN_ERROR);
+ goto fail;
}
break;
case spawn_do_open:
{
- int new_fd = open_not_cancel (action->action.open_action.path,
+ /* POSIX states that if fildes was already an open file descriptor,
+ it shall be closed before the new file is opened. This avoid
+ pontential issues when posix_spawn plus addopen action is called
+ with the process already at maximum number of file descriptor
+ opened and also for multiple actions on single-open special
+ paths (like /dev/watchdog). */
+ __close_nocancel (action->action.open_action.fd);
+
+ int new_fd = __open_nocancel (action->action.open_action.path,
action->action.open_action.oflag
| O_LARGEFILE,
action->action.open_action.mode);
if (new_fd == -1)
- /* The `open' call failed. */
- _exit (SPAWN_ERROR);
+ goto fail;
/* Make sure the desired file descriptor is used. */
if (new_fd != action->action.open_action.fd)
{
if (__dup2 (new_fd, action->action.open_action.fd)
!= action->action.open_action.fd)
- /* The `dup2' call failed. */
- _exit (SPAWN_ERROR);
+ goto fail;
- if (close_not_cancel (new_fd) != 0)
- /* The `close' call failed. */
- _exit (SPAWN_ERROR);
+ if (__close_nocancel (new_fd) != 0)
+ goto fail;
}
}
break;
@@ -230,85 +207,111 @@ __spawni (pid_t *pid, const char *file,
if (__dup2 (action->action.dup2_action.fd,
action->action.dup2_action.newfd)
!= action->action.dup2_action.newfd)
- /* The `dup2' call failed. */
- _exit (SPAWN_ERROR);
+ goto fail;
break;
}
}
}
- if ((xflags & SPAWN_XFLAGS_USE_PATH) == 0 || strchr (file, '/') != NULL)
- {
- /* The FILE parameter is actually a path. */
- __execve (file, argv, envp);
+ /* Set the initial signal mask of the child if POSIX_SPAWN_SETSIGMASK
+ is set, otherwise restore the previous one. */
+ __sigprocmask (SIG_SETMASK, (attr->__flags & POSIX_SPAWN_SETSIGMASK)
+ ? &attr->__ss : &args->oldmask, 0);
+
+ args->exec (args->file, args->argv, args->envp);
+
+ /* This is compatibility function required to enable posix_spawn run
+ script without shebang definition for older posix_spawn versions
+ (2.15). */
+ maybe_script_execute (args);
+
+fail:
+ /* errno should have an appropriate non-zero value; otherwise,
+ there's a bug in glibc or the kernel. For lack of an error code
+ (EINTERNALBUG) describing that, use ECHILD. Another option would
+ be to set args->err to some negative sentinel and have the parent
+ abort(), but that seems needlessly harsh. */
+ ret = errno ? : ECHILD;
+ if (ret)
+ /* Since sizeof errno < PIPE_BUF, the write is atomic. */
+ while (__write_nocancel (args->pipe[1], &ret, sizeof (ret)) < 0);
- maybe_script_execute (file, argv, envp, xflags);
+ _exit (SPAWN_ERROR);
+}
- /* Oh, oh. `execve' returns. This is bad. */
- _exit (SPAWN_ERROR);
- }
+/* Spawn a new process executing PATH with the attributes describes in *ATTRP.
+ Before running the process perform the actions described in FILE-ACTIONS. */
+int
+__spawnix (pid_t *pid, const char *file,
+ const posix_spawn_file_actions_t *file_actions,
+ const posix_spawnattr_t *attrp, char *const argv[],
+ char *const envp[], int xflags,
+ int (*exec) (const char *, char *const *, char *const *))
+{
+ struct posix_spawn_args args;
+ int ec;
- /* We have to search for FILE on the path. */
- path = getenv ("PATH");
- if (path == NULL)
- {
- /* There is no `PATH' in the environment.
- The default search path is the current directory
- followed by the path `confstr' returns for `_CS_PATH'. */
- len = confstr (_CS_PATH, (char *) NULL, 0);
- path = (char *) __alloca (1 + len);
- path[0] = ':';
- (void) confstr (_CS_PATH, path + 1, len);
- }
+ if (__pipe2 (args.pipe, O_CLOEXEC))
+ return errno;
- len = strlen (file) + 1;
- pathlen = strlen (path);
- name = __alloca (pathlen + len + 1);
- /* Copy the file name at the top. */
- name = (char *) memcpy (name + pathlen + 1, file, len);
- /* And add the slash. */
- *--name = '/';
+ /* Disable asynchronous cancellation. */
+ int state;
+ __libc_ptf_call (__pthread_setcancelstate,
+ (PTHREAD_CANCEL_DISABLE, &state), 0);
- p = path;
- do
- {
- char *startp;
+ ptrdiff_t argc = 0;
+ ptrdiff_t limit = INT_MAX - 1;
+ while (argv[argc++] != NULL)
+ if (argc == limit)
+ {
+ errno = E2BIG;
+ return errno;
+ }
- path = p;
- p = __strchrnul (path, ':');
+ args.file = file;
+ args.exec = exec;
+ args.fa = file_actions;
+ args.attr = attrp ? attrp : &(const posix_spawnattr_t) { 0 };
+ args.argv = argv;
+ args.argc = argc;
+ args.envp = envp;
+ args.xflags = xflags;
- if (p == path)
- /* Two adjacent colons, or a colon at the beginning or the end
- of `PATH' means to search the current directory. */
- startp = name + 1;
+ /* Generate the new process. */
+ pid_t new_pid = __fork ();
+
+ if (new_pid == 0)
+ __spawni_child (&args);
+ else if (new_pid > 0)
+ {
+ __close (args.pipe[1]);
+
+ if (__read (args.pipe[0], &ec, sizeof ec) != sizeof ec)
+ ec = 0;
else
- startp = (char *) memcpy (name - (p - path), path, p - path);
+ __waitpid (new_pid, &(int) { 0 }, 0);
+ }
+ else
+ ec = errno;
- /* Try to execute this name. If it works, execv will not return. */
- __execve (startp, argv, envp);
+ __close (args.pipe[0]);
- maybe_script_execute (startp, argv, envp, xflags);
+ if ((ec == 0) && (pid != NULL))
+ *pid = new_pid;
- switch (errno)
- {
- case EACCES:
- case ENOENT:
- case ESTALE:
- case ENOTDIR:
- /* Those errors indicate the file is missing or not executable
- by us, in which case we want to just try the next path
- directory. */
- break;
-
- default:
- /* Some other error means we found an executable file, but
- something went wrong executing it; return the error to our
- caller. */
- _exit (SPAWN_ERROR);
- }
- }
- while (*p++ != '\0');
+ __libc_ptf_call (__pthread_setcancelstate, (state, NULL), 0);
- /* Return with an error. */
- _exit (SPAWN_ERROR);
+ return ec;
+}
+
+int
+__spawni (pid_t * pid, const char *file,
+ const posix_spawn_file_actions_t * acts,
+ const posix_spawnattr_t * attrp, char *const argv[],
+ char *const envp[], int xflags)
+{
+ /* It uses __execvpex to avoid run ENOEXEC in non compatibility mode (it
+ will be handled by maybe_script_execute). */
+ return __spawnix (pid, file, acts, attrp, argv, envp, xflags,
+ xflags & SPAWN_XFLAGS_USE_PATH ? __execvpex : __execve);
}
diff --git a/sysdeps/posix/sprofil.c b/sysdeps/posix/sprofil.c
index b46721a7ce..d9d639aaad 100644
--- a/sysdeps/posix/sprofil.c
+++ b/sysdeps/posix/sprofil.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2016 Free Software Foundation, Inc.
+/* Copyright (C) 2001-2018 Free Software Foundation, Inc.
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>.
This file is part of the GNU C Library.
@@ -21,6 +21,7 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#include <sigsetops.h>
#include <sys/time.h>
#include <sys/profil.h>
diff --git a/sysdeps/posix/sysconf.c b/sysdeps/posix/sysconf.c
index 892f76d55c..8b74ad6184 100644
--- a/sysdeps/posix/sysconf.c
+++ b/sysdeps/posix/sysconf.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -29,6 +29,7 @@
#include <sys/stat.h>
#include <sys/sysinfo.h>
#include <sys/types.h>
+#include <sys/uio.h>
#include <regex.h>
#define NEED_SPEC_ARRAY 0
@@ -93,7 +94,7 @@ __sysconf (int name)
#endif
case _SC_TZNAME_MAX:
- return MAX (__tzname_max (), _POSIX_TZNAME_MAX);
+ return -1;
case _SC_JOB_CONTROL:
#if CONF_IS_DEFINED_SET (_POSIX_JOB_CONTROL)
diff --git a/sysdeps/posix/system.c b/sysdeps/posix/system.c
index 8ed01aa9fb..d7594436ed 100644
--- a/sysdeps/posix/system.c
+++ b/sysdeps/posix/system.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -24,6 +24,7 @@
#include <sys/wait.h>
#include <libc-lock.h>
#include <sysdep-cancel.h>
+#include <sigsetops.h>
#define SHELL_PATH "/bin/sh" /* Path of the shell. */
diff --git a/sysdeps/posix/sysv_signal.c b/sysdeps/posix/sysv_signal.c
index c70f50d01e..2727ab0ee3 100644
--- a/sysdeps/posix/sysv_signal.c
+++ b/sysdeps/posix/sysv_signal.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -18,7 +18,7 @@
#include <errno.h>
#include <signal.h>
#include <string.h> /* For the real memset prototype. */
-
+#include <sigsetops.h>
/* Tolerate non-threads versions of Posix */
#ifndef SA_ONESHOT
@@ -46,8 +46,7 @@ __sysv_signal (int sig, __sighandler_t handler)
}
act.sa_handler = handler;
- if (__sigemptyset (&act.sa_mask) < 0)
- return SIG_ERR;
+ __sigemptyset (&act.sa_mask);
act.sa_flags = SA_ONESHOT | SA_NOMASK | SA_INTERRUPT;
act.sa_flags &= ~SA_RESTART;
if (__sigaction (sig, &act, &oact) < 0)
diff --git a/sysdeps/posix/telldir.c b/sysdeps/posix/telldir.c
index 85dc58bd8a..8caea582f9 100644
--- a/sysdeps/posix/telldir.c
+++ b/sysdeps/posix/telldir.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/posix/tempname.c b/sysdeps/posix/tempname.c
index 93be738e12..432262a03b 100644
--- a/sysdeps/posix/tempname.c
+++ b/sysdeps/posix/tempname.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/posix/time.c b/sysdeps/posix/time.c
index 2afe174788..6d0bb4bafc 100644
--- a/sysdeps/posix/time.c
+++ b/sysdeps/posix/time.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/posix/timespec_get.c b/sysdeps/posix/timespec_get.c
index 01346ab1a9..6a40b64b8c 100644
--- a/sysdeps/posix/timespec_get.c
+++ b/sysdeps/posix/timespec_get.c
@@ -1,5 +1,5 @@
/* timespec_get -- C11 interface to sample a clock. Generic POSIX.1 version.
- Copyright (C) 2013-2016 Free Software Foundation, Inc.
+ Copyright (C) 2013-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/posix/truncate.c b/sysdeps/posix/truncate.c
index 82a77b5a9a..388e87734f 100644
--- a/sysdeps/posix/truncate.c
+++ b/sysdeps/posix/truncate.c
@@ -1,5 +1,5 @@
/* Truncate a file given by name. Generic POSIX.1 version.
- Copyright (C) 1995-2016 Free Software Foundation, Inc.
+ Copyright (C) 1995-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/posix/ttyname.c b/sysdeps/posix/ttyname.c
index 23a250cd9b..3dae5e8411 100644
--- a/sysdeps/posix/ttyname.c
+++ b/sysdeps/posix/ttyname.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -28,13 +28,12 @@
char *__ttyname;
static char *getttyname (int fd, dev_t mydev, ino_t myino,
- int save, int *dostat) internal_function;
+ int save, int *dostat);
libc_freeres_ptr (static char *getttyname_name);
static char *
-internal_function
getttyname (int fd, dev_t mydev, ino_t myino, int save, int *dostat)
{
static const char dev[] = "/dev";
diff --git a/sysdeps/posix/ttyname_r.c b/sysdeps/posix/ttyname_r.c
index 6da98b3510..725de7c4fb 100644
--- a/sysdeps/posix/ttyname_r.c
+++ b/sysdeps/posix/ttyname_r.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -33,10 +33,9 @@ static const char dev[] = "/dev";
static int getttyname_r (int fd, char *buf, size_t buflen,
dev_t mydev, ino_t myino, int save,
- int *dostat) __THROW internal_function;
+ int *dostat) __THROW;
static int
-internal_function
getttyname_r (int fd, char *buf, size_t buflen, dev_t mydev, ino_t myino,
int save, int *dostat)
{
diff --git a/sysdeps/posix/ulimit.c b/sysdeps/posix/ulimit.c
index 47c9ff2e41..3a4c64dc90 100644
--- a/sysdeps/posix/ulimit.c
+++ b/sysdeps/posix/ulimit.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/posix/usleep.c b/sysdeps/posix/usleep.c
index f0e28f2d7a..3a3cd202c9 100644
--- a/sysdeps/posix/usleep.c
+++ b/sysdeps/posix/usleep.c
@@ -1,5 +1,5 @@
/* Implementation of the BSD usleep function using nanosleep.
- Copyright (C) 1996-2016 Free Software Foundation, Inc.
+ Copyright (C) 1996-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
diff --git a/sysdeps/posix/utime.c b/sysdeps/posix/utime.c
index c0d2736ae2..63e4898c8d 100644
--- a/sysdeps/posix/utime.c
+++ b/sysdeps/posix/utime.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 1991-2016 Free Software Foundation, Inc.
+/* utime -- Change access and modification times of file. Posix version.
+ Copyright (C) 1991-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/posix/utimes.c b/sysdeps/posix/utimes.c
index 4dc2946b18..a76eaf18a0 100644
--- a/sysdeps/posix/utimes.c
+++ b/sysdeps/posix/utimes.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 1995-2016 Free Software Foundation, Inc.
+/* utimes -- Change access and modification times of file. Posix version.
+ Copyright (C) 1995-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/sysdeps/posix/wait.c b/sysdeps/posix/wait.c
index 7f1d71a45f..2abcf24ab9 100644
--- a/sysdeps/posix/wait.c
+++ b/sysdeps/posix/wait.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -21,7 +21,7 @@
/* Wait for a child to die. When one does, put its status in *STAT_LOC
and return its process ID. For errors, return (pid_t) -1. */
__pid_t
-__libc_wait (__WAIT_STATUS_DEFN stat_loc)
+__libc_wait (int *stat_loc)
{
return __waitpid (WAIT_ANY, (int *) stat_loc, 0);
}
diff --git a/sysdeps/posix/wait3.c b/sysdeps/posix/wait3.c
index 2e76892bff..c3f977d62b 100644
--- a/sysdeps/posix/wait3.c
+++ b/sysdeps/posix/wait3.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1992-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -26,14 +26,14 @@
there. If the WUNTRACED bit is set in OPTIONS, return status for stopped
children; otherwise don't. */
pid_t
-__wait3 (__WAIT_STATUS stat_loc, int options, struct rusage *usage)
+__wait3 (int *stat_loc, int options, struct rusage *usage)
{
if (usage != NULL)
{
__set_errno (ENOSYS);
return (pid_t) -1;
}
- return __waitpid (WAIT_ANY, stat_loc.__iptr, options);
+ return __waitpid (WAIT_ANY, stat_loc, options);
}
weak_alias (__wait3, wait3)
diff --git a/sysdeps/posix/waitid.c b/sysdeps/posix/waitid.c
index 14bf15e735..3207c742c2 100644
--- a/sysdeps/posix/waitid.c
+++ b/sysdeps/posix/waitid.c
@@ -1,5 +1,5 @@
/* Pseudo implementation of waitid.
- Copyright (C) 1997-2016 Free Software Foundation, Inc.
+ Copyright (C) 1997-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Zack Weinberg <zack@rabi.phys.columbia.edu>, 1997.
@@ -80,7 +80,7 @@ OUR_WAITID (idtype_t idtype, id_t id, siginfo_t *infop, int options)
#endif
#ifdef WEXITED
|| ((options & (WEXITED|WSTOPPED|WCONTINUED))
- != (WEXITED | (options & WUNTRACED)))
+ != (WEXITED | (options & WSTOPPED)))
#endif
)
{
diff --git a/sysdeps/posix/writev.c b/sysdeps/posix/writev.c
index 99edfdfade..dbabe0d9ca 100644
--- a/sysdeps/posix/writev.c
+++ b/sysdeps/posix/writev.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -88,4 +88,5 @@ __writev (int fd, const struct iovec *vector, int count)
return bytes_written;
}
+libc_hidden_def (__writev)
weak_alias (__writev, writev)