+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]
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>
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.
# 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),
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
+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]
wait. */
assert (fd != -1);
- TEMP_FAILURE_RETRY (write (fd, &dataset->resp, total));
+ writeall (fd, &dataset->resp, total);
}
goto out;
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)
{
/* 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);
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)
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)
{
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
{
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)
{
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
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
{
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)
{
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
unnecessarily let the receiver wait. */
assert (fd != -1);
- written = TEMP_FAILURE_RETRY (write (fd, &dataset->resp, total));
+ written = writeall (fd, &dataset->resp, total);
}
#include <sys/types.h>
#include <atomic.h>
#include <nscd-types.h>
+#include <sys/uio.h>
/* Version number of the daemon interface */
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 */
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;
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;
}
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. */
? INADDRSZ : IN6ADDRSZ)))
{
no_room:
+ *h_errnop = NETDB_INTERNAL;
__set_errno (ERANGE);
retval = ERANGE;
goto out_close;
++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
/* 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;
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))
{
#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)
{
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;
}
unnecessarily let the receiver wait. */
assert (fd != -1);
- written = TEMP_FAILURE_RETRY (write (fd, &dataset->resp, total));
+ written = writeall (fd, &dataset->resp, total);
}
{
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)
{
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
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
__set_errno (EACCES);
free (script_argv);
- free (name);
+ free (name - pathlen);
if (path_malloc)
free (path);
}
--- /dev/null
+#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"
--- /dev/null
+#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;
+}
--- /dev/null
+#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"
--- /dev/null
+#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;
+}
--- /dev/null
+#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"
--- /dev/null
+#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;
+}
--- /dev/null
+#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"
--- /dev/null
+#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;
+}
--- /dev/null
+#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"
--- /dev/null
+#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;
+}
--- /dev/null
+#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"
--- /dev/null
+#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;
+}
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));
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
& ~(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. */