about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--io/ftw.c59
-rw-r--r--nptl/ChangeLog5
-rw-r--r--nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h9
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)