changeset 8217:f43bac5db7d2

* lib/getcwd.c (__getcwd): Undo previous change; it mishandled long unreadable paths in GNU/Linux. Problem reported by Andreas Schwab in <http://lists.gnu.org/archive/html/bug-gnulib/2007-02/msg00261.html>. I'll try to think of a better way to fix the Solaris problem.
author Paul Eggert <eggert@cs.ucla.edu>
date Wed, 21 Feb 2007 20:49:59 +0000
parents a45de5ccf3a6
children 75db750f2635
files ChangeLog lib/getcwd.c
diffstat 2 files changed, 24 insertions(+), 24 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Wed Feb 21 08:36:35 2007 +0000
+++ b/ChangeLog	Wed Feb 21 20:49:59 2007 +0000
@@ -1,5 +1,11 @@
 2007-02-21  Paul Eggert  <eggert@cs.ucla.edu>
 
+	* lib/getcwd.c (__getcwd): Undo previous change; it mishandled
+	long unreadable paths in GNU/Linux.  Problem reported by Andreas
+	Schwab in
+	<http://lists.gnu.org/archive/html/bug-gnulib/2007-02/msg00261.html>.
+	I'll try to think of a better way to fix the Solaris problem.
+
 	* lib/getcwd.c (__getcwd): Don't assume getcwd (NULL, 0) works
 	like glibc; on Solaris 10, it fails with errno == EINVAL.
 	POSIX says the behavior is unspecified if the first argument is NULL,
--- a/lib/getcwd.c	Wed Feb 21 08:36:35 2007 +0000
+++ b/lib/getcwd.c	Wed Feb 21 20:49:59 2007 +0000
@@ -141,6 +141,24 @@
   size_t allocated = size;
   size_t used;
 
+#if HAVE_PARTLY_WORKING_GETCWD
+  /* The system getcwd works, except it sometimes fails when it
+     shouldn't, setting errno to ERANGE, ENAMETOOLONG, or ENOENT.  If
+     AT_FDCWD is not defined, the algorithm below is O(N**2) and this
+     is much slower than the system getcwd (at least on GNU/Linux).
+     So trust the system getcwd's results unless they look
+     suspicious.
+
+     Use the system getcwd even if we have openat support, since the
+     system getcwd works even when a parent is unreadable, while the
+     openat-based approach does not.  */
+
+# undef getcwd
+  dir = getcwd (buf, size);
+  if (dir || (errno != ERANGE && !is_ENAMETOOLONG (errno) && errno != ENOENT))
+    return dir;
+#endif
+
   if (size == 0)
     {
       if (buf != NULL)
@@ -161,30 +179,6 @@
   else
     dir = buf;
 
-#if HAVE_PARTLY_WORKING_GETCWD
-  /* The system getcwd works, except it sometimes fails when it
-     shouldn't, setting errno to ERANGE, ENAMETOOLONG, or ENOENT.  If
-     AT_FDCWD is not defined, the algorithm below is O(N**2) and this
-     is much slower than the system getcwd (at least on GNU/Linux).
-     So trust the system getcwd's results unless they look
-     suspicious.
-
-     Use the system getcwd even if we have openat support, since the
-     system getcwd works even when a parent is unreadable, while the
-     openat-based approach does not.  */
-
-# undef getcwd
-  if (getcwd (dir, allocated))
-    {
-      if (buf == NULL && size == 0)
-	buf = realloc (dir, strlen (dir) + 1);
-      return (buf ? buf : dir);
-    }
-
-  if (! (errno == ERANGE || is_ENAMETOOLONG (errno) || errno == ENOENT))
-    return NULL;
-#endif
-
   dirp = dir + allocated;
   *--dirp = '\0';