diff options
author | Paul Eggert <eggert@cs.ucla.edu> | 2007-02-21 08:36:35 +0000 |
---|---|---|
committer | Paul Eggert <eggert@cs.ucla.edu> | 2007-02-21 08:36:35 +0000 |
commit | ea7a4b772f0705edb9c9f2d75125f9849787078a (patch) | |
tree | 1de4f0655d5f09da7e3cce7978748c06d67534c0 /lib/getcwd.c | |
parent | dff73d331c91793b6c616f8ba80244175e54c5b6 (diff) | |
download | gnulib-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.c | 42 |
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'; |