Merge branch 'stable'
[gnulib.git] / lib / getcwd.c
index e52af18..9b8171c 100644 (file)
 
 #include <fcntl.h> /* For AT_FDCWD on Solaris 9.  */
 
-/* If this host provides the openat function, then enable
-   code below to make getcwd more efficient and robust.  */
-#ifdef HAVE_OPENAT
+/* If this host provides the openat function or if we're using the
+   gnulib replacement function, then enable code below to make getcwd
+   more efficient and robust.  */
+#if defined HAVE_OPENAT || defined GNULIB_OPENAT
 # define HAVE_OPENAT_SUPPORT 1
 #else
 # define HAVE_OPENAT_SUPPORT 0
@@ -57,8 +58,6 @@
 # endif
 #endif
 
-#include <limits.h>
-
 #ifndef MAX
 # define MAX(a, b) ((a) < (b) ? (b) : (a))
 #endif
 # define MIN(a, b) ((a) < (b) ? (a) : (b))
 #endif
 
+#include "pathmax.h"
+
+/* In this file, PATH_MAX only serves as a threshold for choosing among two
+   algorithms.  */
 #ifndef PATH_MAX
-# ifdef MAXPATHLEN
-#  define PATH_MAX MAXPATHLEN
-# else
-#  define PATH_MAX 1024
-# endif
+# define PATH_MAX 8192
 #endif
 
 #if D_INO_IN_DIRENT
@@ -136,7 +135,7 @@ __getcwd (char *buf, size_t size)
   size_t allocated = size;
   size_t used;
 
-#if HAVE_RAW_DECL_GETCWD
+#if HAVE_RAW_DECL_GETCWD && HAVE_MINIMALLY_WORKING_GETCWD
   /* 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
@@ -144,11 +143,16 @@ __getcwd (char *buf, size_t size)
 
      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.  */
+     openat-based approach does not.
+
+     But on AIX 5.1..7.1, the system getcwd is not even minimally
+     working: If the current directory name is slightly longer than
+     PATH_MAX, it omits the first directory component and returns
+     this wrong result with errno = 0.  */
 
 # undef getcwd
   dir = getcwd (buf, size);
-  if (dir)
+  if (dir || (size && errno == ERANGE))
     return dir;
 
   /* Solaris getcwd (NULL, 0) fails with errno == EINVAL, but it has