Import upstream version 1.27
[debian/tar] / gnu / getcwd.c
index 011d641776606379554837410cef2e3a8ac71ac5..22ba534ed3beed0b20fa200d3754f2a985956dc4 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- buffer-read-only: t -*- vi: set ro: */
 /* DO NOT EDIT! GENERATED AUTOMATICALLY! */
-/* Copyright (C) 1991-1999, 2004-2011 Free Software Foundation, Inc.
+/* Copyright (C) 1991-1999, 2004-2013 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    This program is free software: you can redistribute it and/or modify
 
 #include <fcntl.h> /* For AT_FDCWD on Solaris 9.  */
 
-/* If this host provides the openat function, then enable
+/* If this host provides the openat function or if we're using the
+   gnulib replacement function with a native fdopendir, then enable
    code below to make getcwd more efficient and robust.  */
-#ifdef HAVE_OPENAT
+#if defined HAVE_OPENAT || (defined GNULIB_OPENAT && defined HAVE_FDOPENDIR)
 # define HAVE_OPENAT_SUPPORT 1
 #else
 # define HAVE_OPENAT_SUPPORT 0
@@ -59,8 +60,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
 /* Get the name of the current working directory, and put it in SIZE
    bytes of BUF.  Returns NULL if the directory couldn't be determined or
    SIZE was too small.  If successful, returns BUF.  In GNU, if BUF is
-   NULL, an array is allocated with `malloc'; the array is SIZE bytes long,
+   NULL, an array is allocated with 'malloc'; the array is SIZE bytes long,
    unless SIZE == 0, in which case it is as big as necessary.  */
 
 char *
@@ -138,7 +137,7 @@ __getcwd (char *buf, size_t size)
   size_t allocated = size;
   size_t used;
 
-#if HAVE_RAW_DECL_GETCWD
+#if 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
@@ -146,11 +145,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
@@ -408,7 +412,7 @@ __getcwd (char *buf, size_t size)
     buf = realloc (dir, used);
 
   if (buf == NULL)
-    /* Either buf was NULL all along, or `realloc' failed but
+    /* Either buf was NULL all along, or 'realloc' failed but
        we still have the original string.  */
     buf = dir;