diff options
-rw-r--r-- | io/ftw.c | 59 | ||||
-rw-r--r-- | nptl/ChangeLog | 5 | ||||
-rw-r--r-- | nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h | 9 |
3 files changed, 48 insertions, 25 deletions
diff --git a/io/ftw.c b/io/ftw.c index 5cd0faf54d..f24a6b46fe 100644 --- a/io/ftw.c +++ b/io/ftw.c @@ -587,6 +587,7 @@ ftw_startup (const char *dir, int is_nftw, void *func, int descriptors, int result = 0; int save_err; int cwdfd = -1; + char *cwd = NULL; char *cp; /* First make sure the parameters are reasonable. */ @@ -645,28 +646,34 @@ ftw_startup (const char *dir, int is_nftw, void *func, int descriptors, descriptor. */ cwdfd = __open (".", O_RDONLY | O_DIRECTORY); if (cwdfd == -1) - result = -1; - else { - if (data.maxdir > 1) - /* Account for the file descriptor we use here. */ - --data.maxdir; + /* Try getting the directory name. This can be needed if + the current directory is executable but not readable. */ + if (errno == EACCES) + /* GNU extension ahead. */ + cwd = __getcwd (NULL, 0); + + if (cwd == NULL) + goto out_fail; + } + else if (data.maxdir > 1) + /* Account for the file descriptor we use here. */ + --data.maxdir; - if (data.ftw.base > 0) + if (data.ftw.base > 0) + { + /* Change to the directory the file is in. In data.dirbuf + we have a writable copy of the file name. Just NUL + terminate it for now and change the directory. */ + if (data.ftw.base == 1) + /* I.e., the file is in the root directory. */ + result = __chdir ("/"); + else { - /* Change to the directory the file is in. In data.dirbuf - we have a writable copy of the file name. Just NUL - terminate it for now and change the directory. */ - if (data.ftw.base == 1) - /* I.e., the file is in the root directory. */ - result = __chdir ("/"); - else - { - char ch = data.dirbuf[data.ftw.base - 1]; - data.dirbuf[data.ftw.base - 1] = '\0'; - result = __chdir (data.dirbuf); - data.dirbuf[data.ftw.base - 1] = ch; - } + char ch = data.dirbuf[data.ftw.base - 1]; + data.dirbuf[data.ftw.base - 1] = '\0'; + result = __chdir (data.dirbuf); + data.dirbuf[data.ftw.base - 1] = ch; } } } @@ -729,8 +736,16 @@ ftw_startup (const char *dir, int is_nftw, void *func, int descriptors, __fchdir (cwdfd); __set_errno (save_err); } + else if (cwd != NULL) + { + int save_err = errno; + __chdir (cwd); + free (cwd); + __set_errno (save_err); + } /* Free all memory. */ + out_fail: save_err = errno; __tdestroy (data.known_objects, free); free (data.dirbuf); @@ -764,7 +779,7 @@ NFTW_NAME (path, func, descriptors, flags) } #else -#include <shlib-compat.h> +# include <shlib-compat.h> int NFTW_NEW_NAME (const char *, NFTW_FUNC_T, int, int); @@ -786,7 +801,7 @@ NFTW_NEW_NAME (path, func, descriptors, flags) versioned_symbol (libc, NFTW_NEW_NAME, NFTW_NAME, GLIBC_2_3_3); -#if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_3_3) +# if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_3_3) /* Older nftw* version just ignored all unknown flags. */ @@ -805,5 +820,5 @@ NFTW_OLD_NAME (path, func, descriptors, flags) } compat_symbol (libc, NFTW_OLD_NAME, NFTW_NAME, GLIBC_2_1); -#endif +# endif #endif diff --git a/nptl/ChangeLog b/nptl/ChangeLog index 54e7ff46a6..bb8e60707e 100644 --- a/nptl/ChangeLog +++ b/nptl/ChangeLog @@ -1,3 +1,8 @@ +2006-02-08 Jakub Jelinek <jakub@redhat.com> + + * sysdeps/unix/sysv/linux/i386/lowlevellock.h (lll_futex_wait, + lll_futex_timedwait, lll_wait_tid): Add "memory" clobber. + 2006-01-20 Kaz Kojima <kkojima@rr.iij4u.or.jp> * sysdeps/unix/sysv/linux/sh/lowlevellock.h (lll_futex_wait): diff --git a/nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h b/nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h index fd1ee4569d..b233d9747f 100644 --- a/nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h +++ b/nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h @@ -75,7 +75,8 @@ : "=a" (__status) \ : "0" (SYS_futex), LLL_EBX_REG (futex), "S" (0), \ "c" (FUTEX_WAIT), "d" (_val), \ - "i" (offsetof (tcbhead_t, sysinfo))); \ + "i" (offsetof (tcbhead_t, sysinfo)) \ + : "memory"); \ __status; \ }) @@ -90,7 +91,8 @@ : "=a" (__status) \ : "0" (SYS_futex), LLL_EBX_REG (futex), "S" (timeout), \ "c" (FUTEX_WAIT), "d" (_val), \ - "i" (offsetof (tcbhead_t, sysinfo))); \ + "i" (offsetof (tcbhead_t, sysinfo)) \ + : "memory"); \ __status; \ }) @@ -346,7 +348,8 @@ extern int lll_unlock_wake_cb (int *__futex) attribute_hidden; : "=&a" (__ignore) \ : "i" (SYS_futex), LLL_EBX_REG (&tid), "S" (0), \ "c" (FUTEX_WAIT), "d" (_tid), \ - "i" (offsetof (tcbhead_t, sysinfo))); \ + "i" (offsetof (tcbhead_t, sysinfo)) \ + : "memory"); \ } while (0) extern int __lll_timedwait_tid (int *tid, const struct timespec *abstime) |