diff --git a/ChangeLog b/ChangeLog index 34ccc10674..a1745185d0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2011-05-13 Eric Blake + + getcwd-lgpl: relax test for FreeBSD + * doc/posix-functions/getcwd.texi (getcwd): Document portability + issue. + * tests/test-getcwd-lgpl.c (main): Relax test. + Reported by Matthias Bolte. + 2011-05-11 Eric Blake test-fflush: silence compiler warning diff --git a/doc/posix-functions/getcwd.texi b/doc/posix-functions/getcwd.texi index 1f6dd187d2..a49a8990dc 100644 --- a/doc/posix-functions/getcwd.texi +++ b/doc/posix-functions/getcwd.texi @@ -11,8 +11,7 @@ Portability problems fixed by either Gnulib module @code{getcwd} or @itemize @item On glibc platforms, @code{getcwd (NULL, n)} allocates memory for the result. -On some other platforms, this call is not allowed. Conversely, mingw fails -to honor non-zero @code{n}. +On some other platforms, this call is not allowed. @item On some platforms, the prototype for @code{getcwd} uses @code{int} instead of @code{size_t} for the size argument: @@ -30,4 +29,11 @@ correctly on some platforms. Portability problems not fixed by Gnulib: @itemize +@item +When using @code{getcwd(NULL, nonzero)}, some platforms, such as glibc +or cygwin, allocate exactly @code{nonzero} bytes and fail with +@code{ERANGE} if it was not big enough, while other platforms, such as +FreeBSD or mingw, ignore the size argument and allocate whatever size +is necessary. If this call succeeds, an application cannot portably +access beyond the string length of the result. @end itemize diff --git a/tests/test-getcwd-lgpl.c b/tests/test-getcwd-lgpl.c index 67ee66d539..69a7b90ecb 100644 --- a/tests/test-getcwd-lgpl.c +++ b/tests/test-getcwd-lgpl.c @@ -65,12 +65,22 @@ main (int argc, char **argv) pwd2 = malloc (len + 2); for ( ; i <= len; i++) { + char *tmp; errno = 0; ASSERT (getcwd (pwd2, i) == NULL); ASSERT (errno == ERANGE); + /* Allow either glibc or BSD behavior, since POSIX allows both. */ errno = 0; - ASSERT (getcwd (NULL, i) == NULL); - ASSERT (errno == ERANGE); + tmp = getcwd (NULL, i); + if (tmp) + { + ASSERT (strcmp (pwd1, tmp) == 0); + free (tmp); + } + else + { + ASSERT (errno == ERANGE); + } } ASSERT (getcwd (pwd2, len + 1) == pwd2); pwd2[len] = '/'; @@ -80,6 +90,11 @@ main (int argc, char **argv) ASSERT (strstr (pwd2, "/../") == NULL); ASSERT (strstr (pwd2 + 1 + (pwd2[1] == '/'), "//") == NULL); + /* Validate a POSIX requirement on size. */ + errno = 0; + ASSERT (getcwd(pwd2, 0) == NULL); + ASSERT (errno == EINVAL); + free (pwd1); free (pwd2);