summaryrefslogtreecommitdiff
path: root/lib/getcwd.c
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2007-02-21 08:36:35 +0000
committerPaul Eggert <eggert@cs.ucla.edu>2007-02-21 08:36:35 +0000
commitea7a4b772f0705edb9c9f2d75125f9849787078a (patch)
tree1de4f0655d5f09da7e3cce7978748c06d67534c0 /lib/getcwd.c
parentdff73d331c91793b6c616f8ba80244175e54c5b6 (diff)
downloadgnulib-ea7a4b772f0705edb9c9f2d75125f9849787078a.tar.gz
* 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, so play it safe and never pass NULL to the system getcwd.
Diffstat (limited to 'lib/getcwd.c')
-rw-r--r--lib/getcwd.c42
1 files changed, 24 insertions, 18 deletions
diff --git a/lib/getcwd.c b/lib/getcwd.c
index f8567bd739..3ccfbdf46a 100644
--- a/lib/getcwd.c
+++ b/lib/getcwd.c
@@ -141,24 +141,6 @@ __getcwd (char *buf, size_t size)
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)
@@ -179,6 +161,30 @@ __getcwd (char *buf, size_t size)
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';