about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRoland McGrath <roland@gnu.org>2005-02-26 02:12:07 +0000
committerRoland McGrath <roland@gnu.org>2005-02-26 02:12:07 +0000
commita873f007cffea32297d52e8f0b19f5981a4e23b4 (patch)
tree91bf845e7c044e95cc27b433b0c5c652068dd0df
parent4d0ac7b9463ba779778bfdbaa84632b635866ae8 (diff)
downloadglibc-a873f007cffea32297d52e8f0b19f5981a4e23b4.tar.gz
glibc-a873f007cffea32297d52e8f0b19f5981a4e23b4.tar.xz
glibc-a873f007cffea32297d52e8f0b19f5981a4e23b4.zip
Updated to fedora-glibc-2_3-20050226T0141
-rw-r--r--ChangeLog94
-rw-r--r--elf/dl-reloc.c4
-rw-r--r--fedora/branch.mk4
-rw-r--r--nptl/ChangeLog11
-rw-r--r--nscd/aicache.c2
-rw-r--r--nscd/connections.c26
-rw-r--r--nscd/grpcache.c7
-rw-r--r--nscd/hstcache.c7
-rw-r--r--nscd/initgrcache.c2
-rw-r--r--nscd/nscd-client.h10
-rw-r--r--nscd/nscd_getai.c3
-rw-r--r--nscd/nscd_getgr_r.c5
-rw-r--r--nscd/nscd_gethst_r.c9
-rw-r--r--nscd/nscd_getpw_r.c2
-rw-r--r--nscd/nscd_helper.c58
-rw-r--r--nscd/nscd_initgroups.c5
-rw-r--r--nscd/pwdcache.c7
-rw-r--r--posix/Makefile5
-rw-r--r--posix/execvp.c2
-rw-r--r--posix/tst-execl1.c22
-rw-r--r--posix/tst-execl2.c58
-rw-r--r--posix/tst-execle1.c22
-rw-r--r--posix/tst-execle2.c58
-rw-r--r--posix/tst-execlp1.c34
-rw-r--r--posix/tst-execlp2.c82
-rw-r--r--posix/tst-execv1.c22
-rw-r--r--posix/tst-execv2.c60
-rw-r--r--posix/tst-execve1.c23
-rw-r--r--posix/tst-execve2.c61
-rw-r--r--posix/tst-execvp1.c34
-rw-r--r--posix/tst-execvp2.c82
-rw-r--r--posix/unistd.h2
-rw-r--r--sysdeps/generic/libc-tls.c5
33 files changed, 784 insertions, 44 deletions
diff --git a/ChangeLog b/ChangeLog
index 91e2f2eb99..bc413ebda0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,93 @@
+2005-02-23  Ulrich Drepper  <drepper@redhat.com>
+
+	[BZ #719]
+	* elf/Makefile: Run tst-tls9-static again.
+
+2005-02-22  Ulrich Drepper  <drepper@redhat.com>
+
+	[BZ #719]
+	* sysdeps/generic/libc-tls.c (static_dtv): Size the same as the
+	slotinfo array.
+	(__libc_setup_tls): Initialize length of DTV based on array length.
+	* elf/dl-load.c: Revert last change.
+	* sysdeps/generic/dl-tls.c: Revert last change.
+
+	* posix/Makefile (tests): Add tst-execvp1, tst-execvp2, tst-execlp1,
+	tst-execlp2, tst-execv1, tst-execv2, tst-execl1, tst-execl2,
+	tst-execve1, tst-execve2, tst-execle1, and tst-execle2.
+	* posix/tst-execl1.c: New file.
+	* posix/tst-execl2.c: New file.
+	* posix/tst-execle1.c: New file.
+	* posix/tst-execle2.c: New file.
+	* posix/tst-execlp1.c: New file.
+	* posix/tst-execlp2.c: New file.
+	* posix/tst-execv1.c: New file.
+	* posix/tst-execv2.c: New file.
+	* posix/tst-execve1.c: New file.
+	* posix/tst-execve2.c: New file.
+	* posix/tst-execvp1.c: New file.
+	* posix/tst-execvp2.c: New file.
+
+2005-02-22  Jakub Jelinek  <jakub@redhat.com>
+
+	[BZ #769]
+	* nscd/nscd-client.h: Include sys/uio.h.
+	(__readall, __readvall, writeall): New prototypes.
+	* nscd/connections.c (writeall): New function.
+	(handle_request): Use it.
+	* nscd/aicache.c (addhstaiX): Likewise.
+	* nscd/initgrcache.c (addinitgroupsX): Likewise.
+	* nscd/hstcache.c (cache_addhst): Likewise.
+	* nscd/grpcache.c (cache_addgr): Likewise.
+	* nscd/pwdcache.c (cache_addpw): Likewise.
+	* nscd/nscd_helper.c (__readall, __readvall): New functions.
+	* nscd/nscd_getai.c (__nscd_getai): Use them.
+	* nscd/nscd_getpw_r.c (__nscd_getpw_r): Likewise.
+	* nscd/nscd_getgr_r.c (__nscd_getgr_r): Likewise.
+	* nscd/nscd_gethst_r.c (__nscd_gethst_r): Likewise.
+	* nscd/nscd_initgroups.c (__nscd_getgrouplist): Likewise.
+
+2005-02-22  Andreas Schwab  <schwab@suse.de>
+
+	* posix/execvp.c (execvp): Fix invalid free.
+
+2005-02-21  Alan Modra <amodra@bigpond.net.au>
+
+	[BZ #719]
+	* elf/dl-reloc.c (_dl_nothread_init_static_tls): Assert that dtv
+	array index is within bounds.
+
+2005-02-21  Ulrich Drepper  <drepper@redhat.com>
+
+	[BZ #719]
+	* elf/dl-load.c: Do not allow PT_TLS in modules loaded in statically
+	linked code.
+	* sysdeps/generic/dl-tls.c [!SHARED]: Don't build _dl_next_tls_modid.
+	* elf/Makefile: Remove rules to build and run tst-tls9-static.
+
+	[BZ #719]
+	* elf/dl-reloc.c (_dl_nothread_init_static_tls): Avoid using
+	THREAD_DTV multiple times, this minimally reduces code size on
+	some archs.
+
+2005-02-21  Jakub Jelinek  <jakub@redhat.com>
+
+	[BZ #768]
+	* nscd/nscd_gethst_r.c (nscd_gethst_r): Set *h_errnop to
+	NETDB_INTERNAL if buffer is too small.
+
+	[BZ #768]
+	* nscd/hstcache.c (INCR): Remove.
+	(addhstbyX): Double buflen in each iteration rather than add INCR.
+	* nscd/grpcache.c: Likewise.
+	* nscd/pwdcache.c: Likewise.
+
+2005-02-21  Ulrich Drepper  <drepper@redhat.com>
+
+	[BZ #767]
+	* posix/unistd.h: symlink and readlink are unconditionally
+	available in the 2001 spec.
+
 2004-07-23  Jakub Jelinek  <jakub@redhat.com>
 
 	[BZ #284]
@@ -20,7 +110,7 @@
 
 2005-02-07  Ulrich Drepper  <drepper@redhat.com>
 
-	* elf/dl-load.c (_dl_map_object_from_fd): Makre sure registers are
+	* elf/dl-load.c (_dl_map_object_from_fd): Make sure registers are
 	set correctly.
 
 2005-01-07  Jakub Jelinek  <jakub@redhat.com>
@@ -178,7 +268,7 @@
 	stack.
 	* posix/execle.c: Likewise.
 	* posix/execlp.c: Likewise.
-	* posix/execlp.c: Likewise.
+	* posix/execvp.c: Likewise.
 	(script_execute): Removed.
 	(allocate_scripts_argv): New function.  Called at most once to
 	allocate memory, not every time a script is run.  Adjust caller.
diff --git a/elf/dl-reloc.c b/elf/dl-reloc.c
index 4004316c5a..893b3c954a 100644
--- a/elf/dl-reloc.c
+++ b/elf/dl-reloc.c
@@ -114,7 +114,9 @@ _dl_nothread_init_static_tls (struct link_map *map)
 # endif
 
   /* Fill in the DTV slot so that a later LD/GD access will find it.  */
-  THREAD_DTV ()[map->l_tls_modid].pointer = dest;
+  dtv_t *dtv = THREAD_DTV ();
+  assert (map->l_tls_modid <= dtv[-1].counter);
+  dtv[map->l_tls_modid].pointer = dest;
 
   /* Initialize the memory.  */
   memset (__mempcpy (dest, map->l_tls_initimage, map->l_tls_initimage_size),
diff --git a/fedora/branch.mk b/fedora/branch.mk
index 6e299c5090..09f6a3a5f4 100644
--- a/fedora/branch.mk
+++ b/fedora/branch.mk
@@ -3,5 +3,5 @@ glibc-branch := fedora-2_3
 glibc-base := glibc-2_3-branch
 DIST_BRANCH := FC-3
 COLLECTION := dist-fc3-updates-candidate
-fedora-2_3-sync-date := 2005-02-18 01:51 UTC
-fedora-2_3-sync-tag := fedora-glibc-2_3-20050218T0151
+fedora-2_3-sync-date := 2005-02-26 01:41 UTC
+fedora-2_3-sync-tag := fedora-glibc-2_3-20050226T0141
diff --git a/nptl/ChangeLog b/nptl/ChangeLog
index 806f077ffb..15cb029545 100644
--- a/nptl/ChangeLog
+++ b/nptl/ChangeLog
@@ -1,3 +1,14 @@
+2005-02-25  Roland McGrath  <roland@redhat.com>
+
+	* alloca_cutoff.c: Correct license text.
+	* tst-unload.c: Likewise.
+	* sysdeps/pthread/allocalim.h: Likewise.
+	* sysdeps/pthread/pt-initfini.c: Likewise.
+	* sysdeps/pthread/bits/libc-lock.h: Likewise.
+	* sysdeps/pthread/bits/sigthread.h: Likewise.
+	* sysdeps/unix/sysv/linux/bits/local_lim.h: Likewise.
+	* sysdeps/unix/sysv/linux/bits/posix_opt.h: Likewise.
+
 2005-01-26  Jakub Jelinek  <jakub@redhat.com>
 
 	[BZ #737]
diff --git a/nscd/aicache.c b/nscd/aicache.c
index 4e0496ff44..6c03cb8754 100644
--- a/nscd/aicache.c
+++ b/nscd/aicache.c
@@ -365,7 +365,7 @@ addhstaiX (struct database_dyn *db, int fd, request_header *req,
 		     wait.  */
 		  assert (fd != -1);
 
-		  TEMP_FAILURE_RETRY (write (fd, &dataset->resp, total));
+		  writeall (fd, &dataset->resp, total);
 		}
 
 	      goto out;
diff --git a/nscd/connections.c b/nscd/connections.c
index aa760e0252..897f4747de 100644
--- a/nscd/connections.c
+++ b/nscd/connections.c
@@ -183,13 +183,28 @@ static int sock;
 unsigned long int client_queued;
 
 
+ssize_t
+writeall (int fd, const void *buf, size_t len)
+{
+  size_t n = len;
+  ssize_t ret;
+  do
+    {
+      ret = TEMP_FAILURE_RETRY (write (fd, buf, n));
+      if (ret <= 0)
+	break;
+      buf = (const char *) buf + ret;
+      n -= ret;
+    }
+  while (n > 0);
+  return ret < 0 ? ret : len - n;
+}
+
+
 /* Initialize database information structures.  */
 void
 nscd_init (void)
 {
-  struct sockaddr_un sock_addr;
-  size_t cnt;
-
   /* Secure mode and unprivileged mode are incompatible */
   if (server_user != NULL && secure_in_use)
     {
@@ -206,7 +221,7 @@ nscd_init (void)
     /* No configuration for this value, assume a default.  */
     nthreads = 2 * lastdb;
 
-  for (cnt = 0; cnt < lastdb; ++cnt)
+  for (size_t cnt = 0; cnt < lastdb; ++cnt)
     if (dbs[cnt].enabled)
       {
 	pthread_rwlock_init (&dbs[cnt].lock, NULL);
@@ -502,6 +517,7 @@ cannot set socket to close on exec: %s; disabling paranoia mode"),
       exit (1);
     }
   /* Bind a name to the socket.  */
+  struct sockaddr_un sock_addr;
   sock_addr.sun_family = AF_UNIX;
   strcpy (sock_addr.sun_path, _PATH_NSCDSOCKET);
   if (bind (sock, (struct sockaddr *) &sock_addr, sizeof (sock_addr)) < 0)
@@ -690,7 +706,7 @@ cannot handle old request version %d; current version is %d"),
       if (cached != NULL)
 	{
 	  /* Hurray it's in the cache.  */
-	  if (TEMP_FAILURE_RETRY (write (fd, cached->data, cached->recsize))
+	  if (writeall (fd, cached->data, cached->recsize)
 	      != cached->recsize
 	      && __builtin_expect (debug_level, 0) > 0)
 	    {
diff --git a/nscd/grpcache.c b/nscd/grpcache.c
index c565f5a682..7b6e223f17 100644
--- a/nscd/grpcache.c
+++ b/nscd/grpcache.c
@@ -292,7 +292,7 @@ cache_addgr (struct database_dyn *db, int fd, request_header *req,
 	     unnecessarily let the receiver wait.  */
 	  assert (fd != -1);
 
-	  written = TEMP_FAILURE_RETRY (write (fd, &dataset->resp, total));
+	  written = writeall (fd, &dataset->resp, total);
 	}
 
       /* Add the record to the database.  But only if it has not been
@@ -429,11 +429,10 @@ addgrbyX (struct database_dyn *db, int fd, request_header *req,
     {
       char *old_buffer = buffer;
       errno = 0;
-#define INCR 1024
 
       if (__builtin_expect (buflen > 32768, 0))
 	{
-	  buflen += INCR;
+	  buflen *= 2;
 	  buffer = (char *) realloc (use_malloc ? buffer : NULL, buflen);
 	  if (buffer == NULL)
 	    {
@@ -454,7 +453,7 @@ addgrbyX (struct database_dyn *db, int fd, request_header *req,
       else
 	/* Allocate a new buffer on the stack.  If possible combine it
 	   with the previously allocated buffer.  */
-	buffer = (char *) extend_alloca (buffer, buflen, buflen + INCR);
+	buffer = (char *) extend_alloca (buffer, buflen, 2 * buflen);
     }
 
 #if 0
diff --git a/nscd/hstcache.c b/nscd/hstcache.c
index 99d2998f49..53a3e47b5d 100644
--- a/nscd/hstcache.c
+++ b/nscd/hstcache.c
@@ -327,7 +327,7 @@ cache_addhst (struct database_dyn *db, int fd, request_header *req,
 	     unnecessarily keep the receiver waiting.  */
 	  assert (fd != -1);
 
-	  written = TEMP_FAILURE_RETRY (write (fd, &dataset->resp, total));
+	  written = writeall (fd, &dataset->resp, total);
 	}
 
       /* Add the record to the database.  But only if it has not been
@@ -453,11 +453,10 @@ addhstbyX (struct database_dyn *db, int fd, request_header *req,
     {
       char *old_buffer = buffer;
       errno = 0;
-#define INCR 1024
 
       if (__builtin_expect (buflen > 32768, 0))
 	{
-	  buflen += INCR;
+	  buflen *= 2;
 	  buffer = (char *) realloc (use_malloc ? buffer : NULL, buflen);
 	  if (buffer == NULL)
 	    {
@@ -478,7 +477,7 @@ addhstbyX (struct database_dyn *db, int fd, request_header *req,
       else
 	/* Allocate a new buffer on the stack.  If possible combine it
 	   with the previously allocated buffer.  */
-	buffer = (char *) extend_alloca (buffer, buflen, buflen + INCR);
+	buffer = (char *) extend_alloca (buffer, buflen, 2 * buflen);
     }
 
 #if 0
diff --git a/nscd/initgrcache.c b/nscd/initgrcache.c
index b46433716b..5f114bb010 100644
--- a/nscd/initgrcache.c
+++ b/nscd/initgrcache.c
@@ -343,7 +343,7 @@ addinitgroupsX (struct database_dyn *db, int fd, request_header *req,
 	     unnecessarily let the receiver wait.  */
 	  assert (fd != -1);
 
-	  written = TEMP_FAILURE_RETRY (write (fd, &dataset->resp, total));
+	  written = writeall (fd, &dataset->resp, total);
 	}
 
 
diff --git a/nscd/nscd-client.h b/nscd/nscd-client.h
index d49cb8136c..53bb4f4f15 100644
--- a/nscd/nscd-client.h
+++ b/nscd/nscd-client.h
@@ -28,6 +28,7 @@
 #include <sys/types.h>
 #include <atomic.h>
 #include <nscd-types.h>
+#include <sys/uio.h>
 
 
 /* Version number of the daemon interface */
@@ -309,4 +310,13 @@ extern const struct datahead *__nscd_cache_search (request_type type,
 						   size_t keylen,
 						   const struct mapped_database *mapped);
 
+/* Wrappers around read, readv and write that only read/write less than LEN
+   bytes on error or EOF.  */
+extern ssize_t __readall (int fd, void *buf, size_t len)
+  attribute_hidden;
+extern ssize_t __readvall (int fd, const struct iovec *iov, int iovcnt)
+  attribute_hidden;
+extern ssize_t writeall (int fd, const void *buf, size_t len)
+  attribute_hidden;
+
 #endif /* nscd.h */
diff --git a/nscd/nscd_getai.c b/nscd/nscd_getai.c
index cfb3fe2701..ad7664ca23 100644
--- a/nscd/nscd_getai.c
+++ b/nscd/nscd_getai.c
@@ -119,8 +119,7 @@ __nscd_getai (const char *key, struct nscd_ai_result **result, int *h_errnop)
       if (respdata == NULL)
 	{
 	  /* Read the data from the socket.  */
-	  if ((size_t) TEMP_FAILURE_RETRY (__read (sock, resultbuf + 1,
-						   datalen)) == datalen)
+	  if ((size_t) __readall (sock, resultbuf + 1, datalen) == datalen)
 	    {
 	      retval = 0;
 	      *result = resultbuf;
diff --git a/nscd/nscd_getgr_r.c b/nscd/nscd_getgr_r.c
index 282912db3e..a025cf53ca 100644
--- a/nscd/nscd_getgr_r.c
+++ b/nscd/nscd_getgr_r.c
@@ -202,7 +202,7 @@ nscd_getgr_r (const char *key, size_t keylen, request_type type,
 	  total_len = vec[0].iov_len + vec[1].iov_len;
 
 	  /* Get this data.  */
-	  size_t n = TEMP_FAILURE_RETRY (__readv (sock, vec, 2));
+	  size_t n = __readvall (sock, vec, 2);
 	  if (__builtin_expect (n != total_len, 0))
 	    goto out_close;
 	}
@@ -232,8 +232,7 @@ nscd_getgr_r (const char *key, size_t keylen, request_type type,
       retval = 0;
       if (gr_name == NULL)
 	{
-	  size_t n = TEMP_FAILURE_RETRY (__read (sock, resultbuf->gr_mem[0],
-						 total_len));
+	  size_t n = __readall (sock, resultbuf->gr_mem[0], total_len);
 	  if (__builtin_expect (n != total_len, 0))
 	    {
 	      /* The `errno' to some value != ERANGE.  */
diff --git a/nscd/nscd_gethst_r.c b/nscd/nscd_gethst_r.c
index 5d9d569107..e13e2ed106 100644
--- a/nscd/nscd_gethst_r.c
+++ b/nscd/nscd_gethst_r.c
@@ -218,6 +218,7 @@ nscd_gethst_r (const char *key, size_t keylen, request_type type,
 						   ? INADDRSZ : IN6ADDRSZ)))
 	{
 	no_room:
+	  *h_errnop = NETDB_INTERNAL;
 	  __set_errno (ERANGE);
 	  retval = ERANGE;
 	  goto out_close;
@@ -298,8 +299,7 @@ nscd_gethst_r (const char *key, size_t keylen, request_type type,
 	      ++n;
 	    }
 
-	  if ((size_t) TEMP_FAILURE_RETRY (__readv (sock, vec, n))
-	      != total_len)
+	  if ((size_t) __readvall (sock, vec, n) != total_len)
 	    goto out_close;
 	}
       else
@@ -328,9 +328,8 @@ nscd_gethst_r (const char *key, size_t keylen, request_type type,
       /* And finally read the aliases.  */
       if (addr_list == NULL)
 	{
-	  if ((size_t) TEMP_FAILURE_RETRY (__read (sock,
-						   resultbuf->h_aliases[0],
-						   total_len)) == total_len)
+	  if ((size_t) __readall (sock, resultbuf->h_aliases[0], total_len)
+	      == total_len)
 	    {
 	      retval = 0;
 	      *result = resultbuf;
diff --git a/nscd/nscd_getpw_r.c b/nscd/nscd_getpw_r.c
index fe5fb43ca1..d492b67f78 100644
--- a/nscd/nscd_getpw_r.c
+++ b/nscd/nscd_getpw_r.c
@@ -172,7 +172,7 @@ nscd_getpw_r (const char *key, size_t keylen, request_type type,
       retval = 0;
       if (pw_name == NULL)
 	{
-	  ssize_t nbytes = TEMP_FAILURE_RETRY (__read (sock, buffer, total));
+	  ssize_t nbytes = __readall (sock, buffer, total);
 
 	  if (__builtin_expect (nbytes != total, 0))
 	    {
diff --git a/nscd/nscd_helper.c b/nscd/nscd_helper.c
index 0e16cb8aeb..12c10664af 100644
--- a/nscd/nscd_helper.c
+++ b/nscd/nscd_helper.c
@@ -34,6 +34,64 @@
 #include "nscd-client.h"
 
 
+ssize_t
+__readall (int fd, void *buf, size_t len)
+{
+  size_t n = len;
+  ssize_t ret;
+  do
+    {
+      ret = TEMP_FAILURE_RETRY (__read (fd, buf, n));
+      if (ret <= 0)
+	break;
+      buf = (char *) buf + ret;
+      n -= ret;
+    }
+  while (n > 0);
+  return ret < 0 ? ret : len - n;
+}
+
+
+ssize_t
+__readvall (int fd, const struct iovec *iov, int iovcnt)
+{
+  ssize_t ret = TEMP_FAILURE_RETRY (__readv (fd, iov, iovcnt));
+  if (ret <= 0)
+    return ret;
+
+  size_t total = 0;
+  for (int i = 0; i < iovcnt; ++i)
+    total += iov[i].iov_len;
+
+  if (ret < total)
+    {
+      struct iovec iov_buf[iovcnt];
+      ssize_t r = ret;
+
+      struct iovec *iovp = memcpy (iov_buf, iov, iovcnt * sizeof (*iov));
+      do
+	{
+	  while (iovp->iov_len <= r)
+	    {
+	      r -= iovp->iov_len;
+	      --iovcnt;
+	      ++iovp;
+	    }
+	  iovp->iov_base = (char *) iovp->iov_base + r;
+	  iovp->iov_len -= r;
+	  r = TEMP_FAILURE_RETRY (__readv (fd, iovp, iovcnt));
+	  if (r <= 0)
+	    break;
+	  ret += r;
+	}
+      while (ret < total);
+      if (r < 0)
+	ret = r;
+    }
+  return ret;
+}
+
+
 static int
 open_socket (void)
 {
diff --git a/nscd/nscd_initgroups.c b/nscd/nscd_initgroups.c
index a25f1fbcd7..947414eb9e 100644
--- a/nscd/nscd_initgroups.c
+++ b/nscd/nscd_initgroups.c
@@ -110,9 +110,8 @@ __nscd_getgrouplist (const char *user, gid_t group, long int *size,
       if (respdata == NULL)
 	{
 	  /* Read the data from the socket.  */
-	  if ((size_t) TEMP_FAILURE_RETRY (__read (sock, *groupsp,
-						   initgr_resp->ngrps
-						   * sizeof (gid_t)))
+	  if ((size_t) __readall (sock, *groupsp, initgr_resp->ngrps
+						  * sizeof (gid_t))
 	      == initgr_resp->ngrps * sizeof (gid_t))
 	    retval = initgr_resp->ngrps;
 	}
diff --git a/nscd/pwdcache.c b/nscd/pwdcache.c
index e8b9578778..010cf0c65b 100644
--- a/nscd/pwdcache.c
+++ b/nscd/pwdcache.c
@@ -287,7 +287,7 @@ cache_addpw (struct database_dyn *db, int fd, request_header *req,
 	     unnecessarily let the receiver wait.  */
 	  assert (fd != -1);
 
-	  written = TEMP_FAILURE_RETRY (write (fd, &dataset->resp, total));
+	  written = writeall (fd, &dataset->resp, total);
 	}
 
 
@@ -425,11 +425,10 @@ addpwbyX (struct database_dyn *db, int fd, request_header *req,
     {
       char *old_buffer = buffer;
       errno = 0;
-#define INCR 1024
 
       if (__builtin_expect (buflen > 32768, 0))
 	{
-	  buflen += INCR;
+	  buflen *= 2;
 	  buffer = (char *) realloc (use_malloc ? buffer : NULL, buflen);
 	  if (buffer == NULL)
 	    {
@@ -450,7 +449,7 @@ addpwbyX (struct database_dyn *db, int fd, request_header *req,
       else
 	/* Allocate a new buffer on the stack.  If possible combine it
 	   with the previously allocated buffer.  */
-	buffer = (char *) extend_alloca (buffer, buflen, buflen + INCR);
+	buffer = (char *) extend_alloca (buffer, buflen, 2 * buflen);
     }
 
 #if 0
diff --git a/posix/Makefile b/posix/Makefile
index 2a6f737165..4fa8fb7c19 100644
--- a/posix/Makefile
+++ b/posix/Makefile
@@ -83,7 +83,10 @@ tests		:= tstgetopt testfnm runtests runptests	     \
 		   tst-nice tst-nanosleep tst-regex2 \
 		   transbug tst-rxspencer tst-pcre tst-boost \
 		   bug-ga1 tst-vfork1 tst-vfork2 tst-waitid \
-		   tst-getaddrinfo2 bug-glob1 bug-glob2 tst-sysconf
+		   tst-getaddrinfo2 bug-glob1 bug-glob2 tst-sysconf \
+		   tst-execvp1 tst-execvp2 tst-execlp1 tst-execlp2 \
+		   tst-execv1 tst-execv2 tst-execl1 tst-execl2 \
+		   tst-execve1 tst-execve2 tst-execle1 tst-execle2
 xtests		:= bug-ga2
 ifeq (yes,$(build-shared))
 test-srcs	:= globtest
diff --git a/posix/execvp.c b/posix/execvp.c
index a79d4a89c5..9809769701 100644
--- a/posix/execvp.c
+++ b/posix/execvp.c
@@ -189,7 +189,7 @@ execvp (file, argv)
 	__set_errno (EACCES);
 
       free (script_argv);
-      free (name);
+      free (name - pathlen);
       if (path_malloc)
 	free (path);
     }
diff --git a/posix/tst-execl1.c b/posix/tst-execl1.c
new file mode 100644
index 0000000000..1cfa36df12
--- /dev/null
+++ b/posix/tst-execl1.c
@@ -0,0 +1,22 @@
+#include <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+
+static int
+do_test (void)
+{
+  static const char prog[] = "does-not-exist";
+  errno = 0;
+  execl (prog, prog, NULL);
+
+  if (errno != ENOENT)
+    {
+      printf ("errno = %d (%m), expected ENOENT\n", errno);
+      return 1;
+    }
+
+  return 0;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/posix/tst-execl2.c b/posix/tst-execl2.c
new file mode 100644
index 0000000000..5b74959ef8
--- /dev/null
+++ b/posix/tst-execl2.c
@@ -0,0 +1,58 @@
+#include <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/stat.h>
+
+
+static void prepare (int argc, char *argv[]);
+static int do_test (void);
+#define PREPARE(argc, argv) prepare (argc, argv)
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
+
+
+static char *copy;
+
+static void
+prepare (int argc, char *argv[])
+{
+  char *buf;
+  int off;
+  asprintf (&buf, "cp %s %n%s-copy", argv[0], &off, argv[0]);
+  if (buf == NULL)
+    {
+      puts ("asprintf  failed");
+      exit (1);
+    }
+  if (system (buf) != 0)
+    {
+      puts ("system  failed");
+      exit (1);
+    }
+
+  /* Make it not executable.  */
+  copy = buf + off;
+  if (chmod (copy, 0666) != 0)
+    {
+      puts ("chmod  failed");
+      exit (1);
+    }
+
+  add_temp_file (copy);
+}
+
+
+static int
+do_test (void)
+{
+  errno = 0;
+  execl (copy, copy, NULL);
+
+  if (errno != EACCES)
+    {
+      printf ("errno = %d (%m), expected EACCES\n", errno);
+      return 1;
+    }
+
+  return 0;
+}
diff --git a/posix/tst-execle1.c b/posix/tst-execle1.c
new file mode 100644
index 0000000000..adea0a8d46
--- /dev/null
+++ b/posix/tst-execle1.c
@@ -0,0 +1,22 @@
+#include <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+
+static int
+do_test (void)
+{
+  static const char prog[] = "does-not-exist";
+  errno = 0;
+  execle (prog, prog, NULL, "FOO=BAR", NULL);
+
+  if (errno != ENOENT)
+    {
+      printf ("errno = %d (%m), expected ENOENT\n", errno);
+      return 1;
+    }
+
+  return 0;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/posix/tst-execle2.c b/posix/tst-execle2.c
new file mode 100644
index 0000000000..fb9b09b423
--- /dev/null
+++ b/posix/tst-execle2.c
@@ -0,0 +1,58 @@
+#include <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/stat.h>
+
+
+static void prepare (int argc, char *argv[]);
+static int do_test (void);
+#define PREPARE(argc, argv) prepare (argc, argv)
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
+
+
+static char *copy;
+
+static void
+prepare (int argc, char *argv[])
+{
+  char *buf;
+  int off;
+  asprintf (&buf, "cp %s %n%s-copy", argv[0], &off, argv[0]);
+  if (buf == NULL)
+    {
+      puts ("asprintf  failed");
+      exit (1);
+    }
+  if (system (buf) != 0)
+    {
+      puts ("system  failed");
+      exit (1);
+    }
+
+  /* Make it not executable.  */
+  copy = buf + off;
+  if (chmod (copy, 0666) != 0)
+    {
+      puts ("chmod  failed");
+      exit (1);
+    }
+
+  add_temp_file (copy);
+}
+
+
+static int
+do_test (void)
+{
+  errno = 0;
+  execle (copy, copy, NULL, "FOO=BAR", NULL);
+
+  if (errno != EACCES)
+    {
+      printf ("errno = %d (%m), expected EACCES\n", errno);
+      return 1;
+    }
+
+  return 0;
+}
diff --git a/posix/tst-execlp1.c b/posix/tst-execlp1.c
new file mode 100644
index 0000000000..1be4dbcb1b
--- /dev/null
+++ b/posix/tst-execlp1.c
@@ -0,0 +1,34 @@
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+static int
+do_test (void)
+{
+  char *cwd = get_current_dir_name ();
+  if (cwd == NULL)
+    {
+      puts ("get_current_dir_name failed");
+      return 1;
+    }
+
+  /* Make sure we do not find a binary with the name we are going to
+     use.  */
+  setenv ("PATH", cwd, 1);
+
+  static const char prog[] = "does-not-exist";
+  errno = 0;
+  execlp (prog, prog, NULL);
+
+  if (errno != ENOENT)
+    {
+      printf ("errno = %d (%m), expected ENOENT\n", errno);
+      return 1;
+    }
+
+  return 0;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/posix/tst-execlp2.c b/posix/tst-execlp2.c
new file mode 100644
index 0000000000..81a723dda4
--- /dev/null
+++ b/posix/tst-execlp2.c
@@ -0,0 +1,82 @@
+#include <errno.h>
+#include <libgen.h>
+#undef basename
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/stat.h>
+
+
+static void prepare (int argc, char *argv[]);
+static int do_test (void);
+#define PREPARE(argc, argv) prepare (argc, argv)
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
+
+
+static char *copy;
+
+static void
+prepare (int argc, char *argv[])
+{
+  char *buf;
+  int off;
+  asprintf (&buf, "cp %s %n%s-copy", argv[0], &off, argv[0]);
+  if (buf == NULL)
+    {
+      puts ("asprintf  failed");
+      exit (1);
+    }
+  if (system (buf) != 0)
+    {
+      puts ("system  failed");
+      exit (1);
+    }
+
+  /* Make it not executable.  */
+  copy = buf + off;
+  if (chmod (copy, 0666) != 0)
+    {
+      puts ("chmod  failed");
+      exit (1);
+    }
+
+  add_temp_file (copy);
+}
+
+
+static int
+do_test (void)
+{
+  /* Make sure we do not find a binary with the name we are going to
+     use.  */
+  char *bindir = strdupa (copy);
+  bindir = canonicalize_file_name (dirname (bindir));
+  if (bindir == NULL)
+    {
+      puts ("canonicalize_file_name failed");
+      return 1;
+    }
+  char *path;
+  asprintf (&path, "%s:../libio:../elf", bindir);
+  if (path == NULL)
+    {
+      puts ("asprintf  failed");
+      return 1;
+    }
+
+  setenv ("PATH", path, 1);
+
+  char *prog = basename (copy);
+  errno = 0;
+  execlp (prog, prog, NULL);
+
+  if (errno != EACCES)
+    {
+      printf ("errno = %d (%m), expected EACCES\n", errno);
+      return 1;
+    }
+
+  return 0;
+}
diff --git a/posix/tst-execv1.c b/posix/tst-execv1.c
new file mode 100644
index 0000000000..57ed1add6e
--- /dev/null
+++ b/posix/tst-execv1.c
@@ -0,0 +1,22 @@
+#include <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+
+static int
+do_test (void)
+{
+  char *argv[] = { (char *) "does-not-exist", NULL };
+  errno = 0;
+  execv (argv[0], argv);
+
+  if (errno != ENOENT)
+    {
+      printf ("errno = %d (%m), expected ENOENT\n", errno);
+      return 1;
+    }
+
+  return 0;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/posix/tst-execv2.c b/posix/tst-execv2.c
new file mode 100644
index 0000000000..a5168a269c
--- /dev/null
+++ b/posix/tst-execv2.c
@@ -0,0 +1,60 @@
+#include <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/stat.h>
+
+
+static void prepare (int argc, char *argv[]);
+static int do_test (void);
+#define PREPARE(argc, argv) prepare (argc, argv)
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
+
+
+static char *copy;
+
+static void
+prepare (int argc, char *argv[])
+{
+  char *buf;
+  int off;
+  asprintf (&buf, "cp %s %n%s-copy", argv[0], &off, argv[0]);
+  if (buf == NULL)
+    {
+      puts ("asprintf  failed");
+      exit (1);
+    }
+  if (system (buf) != 0)
+    {
+      puts ("system  failed");
+      exit (1);
+    }
+
+  /* Make it not executable.  */
+  copy = buf + off;
+  if (chmod (copy, 0666) != 0)
+    {
+      puts ("chmod  failed");
+      exit (1);
+    }
+
+  add_temp_file (copy);
+}
+
+
+static int
+do_test (void)
+{
+  char *argv[] = { copy, NULL };
+
+  errno = 0;
+  execv (copy, argv);
+
+  if (errno != EACCES)
+    {
+      printf ("errno = %d (%m), expected EACCES\n", errno);
+      return 1;
+    }
+
+  return 0;
+}
diff --git a/posix/tst-execve1.c b/posix/tst-execve1.c
new file mode 100644
index 0000000000..356610f635
--- /dev/null
+++ b/posix/tst-execve1.c
@@ -0,0 +1,23 @@
+#include <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+
+static int
+do_test (void)
+{
+  char *argv[] = { (char *) "does-not-exist", NULL };
+  char *envp[] = { (char *) "FOO=BAR", NULL };
+  errno = 0;
+  execve (argv[0], argv, envp);
+
+  if (errno != ENOENT)
+    {
+      printf ("errno = %d (%m), expected ENOENT\n", errno);
+      return 1;
+    }
+
+  return 0;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/posix/tst-execve2.c b/posix/tst-execve2.c
new file mode 100644
index 0000000000..1a804e94fd
--- /dev/null
+++ b/posix/tst-execve2.c
@@ -0,0 +1,61 @@
+#include <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/stat.h>
+
+
+static void prepare (int argc, char *argv[]);
+static int do_test (void);
+#define PREPARE(argc, argv) prepare (argc, argv)
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
+
+
+static char *copy;
+
+static void
+prepare (int argc, char *argv[])
+{
+  char *buf;
+  int off;
+  asprintf (&buf, "cp %s %n%s-copy", argv[0], &off, argv[0]);
+  if (buf == NULL)
+    {
+      puts ("asprintf  failed");
+      exit (1);
+    }
+  if (system (buf) != 0)
+    {
+      puts ("system  failed");
+      exit (1);
+    }
+
+  /* Make it not executable.  */
+  copy = buf + off;
+  if (chmod (copy, 0666) != 0)
+    {
+      puts ("chmod  failed");
+      exit (1);
+    }
+
+  add_temp_file (copy);
+}
+
+
+static int
+do_test (void)
+{
+  char *argv[] = { copy, NULL };
+  char *envp[] = { (char *) "FOO=BAR", NULL };
+
+  errno = 0;
+  execve (copy, argv, envp);
+
+  if (errno != EACCES)
+    {
+      printf ("errno = %d (%m), expected EACCES\n", errno);
+      return 1;
+    }
+
+  return 0;
+}
diff --git a/posix/tst-execvp1.c b/posix/tst-execvp1.c
new file mode 100644
index 0000000000..ecc673d124
--- /dev/null
+++ b/posix/tst-execvp1.c
@@ -0,0 +1,34 @@
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+static int
+do_test (void)
+{
+  char *cwd = get_current_dir_name ();
+  if (cwd == NULL)
+    {
+      puts ("get_current_dir_name failed");
+      return 1;
+    }
+
+  /* Make sure we do not find a binary with the name we are going to
+     use.  */
+  setenv ("PATH", cwd, 1);
+
+  char *argv[] = { (char *) "does-not-exist", NULL };
+  errno = 0;
+  execvp (argv[0], argv);
+
+  if (errno != ENOENT)
+    {
+      printf ("errno = %d (%m), expected ENOENT\n", errno);
+      return 1;
+    }
+
+  return 0;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/posix/tst-execvp2.c b/posix/tst-execvp2.c
new file mode 100644
index 0000000000..7e0f5d882c
--- /dev/null
+++ b/posix/tst-execvp2.c
@@ -0,0 +1,82 @@
+#include <errno.h>
+#include <libgen.h>
+#undef basename
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/stat.h>
+
+
+static void prepare (int argc, char *argv[]);
+static int do_test (void);
+#define PREPARE(argc, argv) prepare (argc, argv)
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
+
+
+static char *copy;
+
+static void
+prepare (int argc, char *argv[])
+{
+  char *buf;
+  int off;
+  asprintf (&buf, "cp %s %n%s-copy", argv[0], &off, argv[0]);
+  if (buf == NULL)
+    {
+      puts ("asprintf  failed");
+      exit (1);
+    }
+  if (system (buf) != 0)
+    {
+      puts ("system  failed");
+      exit (1);
+    }
+
+  /* Make it not executable.  */
+  copy = buf + off;
+  if (chmod (copy, 0666) != 0)
+    {
+      puts ("chmod  failed");
+      exit (1);
+    }
+
+  add_temp_file (copy);
+}
+
+
+static int
+do_test (void)
+{
+  /* Make sure we do not find a binary with the name we are going to
+     use.  */
+  char *bindir = strdupa (copy);
+  bindir = canonicalize_file_name (dirname (bindir));
+  if (bindir == NULL)
+    {
+      puts ("canonicalize_file_name failed");
+      return 1;
+    }
+  char *path;
+  asprintf (&path, "%s:../libio:../elf", bindir);
+  if (path == NULL)
+    {
+      puts ("asprintf  failed");
+      return 1;
+    }
+
+  setenv ("PATH", path, 1);
+
+  char *argv[] = { basename (copy), NULL };
+  errno = 0;
+  execvp (argv[0], argv);
+
+  if (errno != EACCES)
+    {
+      printf ("errno = %d (%m), expected EACCES\n", errno);
+      return 1;
+    }
+
+  return 0;
+}
diff --git a/posix/unistd.h b/posix/unistd.h
index bf66f7543a..aa568dc93a 100644
--- a/posix/unistd.h
+++ b/posix/unistd.h
@@ -728,7 +728,7 @@ extern int ttyslot (void) __THROW;
 extern int link (__const char *__from, __const char *__to)
      __THROW __nonnull ((1, 2));
 
-#if defined __USE_BSD || defined __USE_XOPEN_EXTENDED
+#if defined __USE_BSD || defined __USE_XOPEN_EXTENDED || defined __USE_XOPEN2K
 /* Make a symbolic link to FROM named TO.  */
 extern int symlink (__const char *__from, __const char *__to)
      __THROW __nonnull ((1, 2));
diff --git a/sysdeps/generic/libc-tls.c b/sysdeps/generic/libc-tls.c
index b5ecc36436..29d9d1e7ea 100644
--- a/sysdeps/generic/libc-tls.c
+++ b/sysdeps/generic/libc-tls.c
@@ -34,8 +34,7 @@ extern ElfW(Phdr) *_dl_phdr;
 extern size_t _dl_phnum;
 
 
-/* DTV with just one element plus overhead.  */
-static dtv_t static_dtv[3];
+static dtv_t static_dtv[2 + TLS_SLOTINFO_SURPLUS];
 
 
 static struct
@@ -173,7 +172,7 @@ __libc_setup_tls (size_t tcbsize, size_t tcbalign)
 		       & ~(max_align - 1));
 
   /* Initialize the dtv.  [0] is the length, [1] the generation counter.  */
-  static_dtv[0].counter = 1;
+  static_dtv[0].counter = (sizeof (static_dtv) / sizeof (static_dtv[0])) - 2;
   // static_dtv[1].counter = 0;		would be needed if not already done
 
   /* Initialize the TLS block.  */