Hi Jim, Getting back to this issue from last Monday:
> > If we fix Eric's typo, REPLACE_GETCWD will come out as 0 on OpenBSD and > > NetBSD. > > Do you know how that happens, given the corrected code? It's because of the details in m4/getcwd-abort-bug.m4. > The part that is surprising is that they would have > $gl_cv_func_getcwd_path_max = yes. > That would mean that getcwd (NULL, 0) can succeed when called > from a directory whose name is longer than PATH_MAX. No, it doesn't succeed. But the logic at the end of m4/getcwd-abort-bug.m4 claims that this failure was a success. > > Can packages that use gnulib's getcwd() module - including coreutils - > > expect that in normal conditions (no EPERM anywhere) > > mkdir ("subdir1", 0700); > > chdir ("subdir1"); > > mkdir ("subdir2", 0700); > > chdir ("subdir2"); > > ... > > mkdir ("subdir1000", 0700); > > chdir ("subdir1000"); > > dir = getcwd (NULL, 0); > > produces a non-NULL dir (longer than PATH_MAX) ? > > Yes, assuming that nothing else goes wrong. Thanks, this is clear. > > So what you are saying is that the unit test and the documentation are > > correct, and only the getcwd*.m4 files need to be changed so as to activate > > the replacement in lib/getcwd.c. This replacement will first call the > > system's getcwd() function, so as to handle file names shorter than PATH_MAX > > with inaccessible parents. > > > > Is that what you mean? > > Yes. OK, clear. > I think Eric proposed some POSIX wording change that would > allow gnulib's getcwd to be considered compliant. OK, I try to avoid making a firm claim about what POSIX says in this area. I'm applying this fix. 2011-11-27 Bruno Haible <br...@clisp.org> getcwd: Fix bug from 2011-08-17. * m4/getcwd.m4 (gl_FUNC_GETCWD): Set REPLACE_GETCWD to 1 only on platforms that need it. * m4/getcwd-abort-bug.m4 (gl_FUNC_GETCWD_ABORT_BUG): Consider a return code of 4 to be a failure, not a success. This ensures that REPLACE_GETCWD becomes 1 on OpenBSD 4.9 and NetBSD 5.1. --- m4/getcwd-abort-bug.m4.orig Mon Nov 28 00:00:21 2011 +++ m4/getcwd-abort-bug.m4 Sun Nov 27 23:50:37 2011 @@ -1,4 +1,4 @@ -# serial 6 +# serial 7 # Determine whether getcwd aborts when the length of the working directory # name is unusually large. Any length between 4k and 16k trigger the bug # when using glibc-2.4.90-9 or older. @@ -91,7 +91,8 @@ results in a failed assertion. */ cwd = getcwd (NULL, 0); if (cwd == NULL) - fail = 4; /* getcwd failed. This is ok, and expected. */ + fail = 4; /* getcwd failed: it refuses to return a string longer + than PATH_MAX. */ free (cwd); /* Call rmdir first, in case the above chdir failed. */ @@ -110,11 +111,18 @@ } ]])], [gl_cv_func_getcwd_abort_bug=no], - dnl A "regular" nonzero return does not indicate this bug. - dnl An abort will provoke an exit code of something like 134 (128 + 6). - [test $? -gt 128 \ - && gl_cv_func_getcwd_abort_bug=yes \ - || gl_cv_func_getcwd_abort_bug=no], + [dnl An abort will provoke an exit code of something like 134 (128 + 6). + dnl An exit code of 4 can also occur (in OpenBSD 4.9, NetBSD 5.1 for + dnl example): getcwd (NULL, 0) fails rather than returning a string + dnl longer than PATH_MAX. This may be POSIX compliant (in some + dnl interpretations of POSIX). But gnulib's getcwd module wants to + dnl provide a non-NULL value in this case. + ret=$? + if test $ret -ge 128 || test $ret = 4; then + gl_cv_func_getcwd_abort_bug=yes + else + gl_cv_func_getcwd_abort_bug=no + fi], [gl_cv_func_getcwd_abort_bug=yes]) ]) AS_IF([test $gl_cv_func_getcwd_abort_bug = yes], [$1], [$2]) --- m4/getcwd.m4.orig Mon Nov 28 00:00:21 2011 +++ m4/getcwd.m4 Sun Nov 27 23:37:22 2011 @@ -6,7 +6,7 @@ # with or without modifications, as long as this notice is preserved. # Written by Paul Eggert. -# serial 10 +# serial 11 AC_DEFUN([gl_FUNC_GETCWD_NULL], [ @@ -139,12 +139,12 @@ ;; esac - case $gl_cv_func_getcwd_null,$gl_cv_func_getcwd_posix_signature$gl_cv_func_getcwd_path_max,$gl_abort_bug in - *yes,yes,yes,no) ;; - *) - dnl Full replacement lib/getcwd.c, overrides LGPL replacement. - REPLACE_GETCWD=1;; - esac + if { case "$gl_cv_func_getcwd_null" in *yes) false;; *) true;; esac; } \ + || test $gl_cv_func_getcwd_posix_signature != yes \ + || test "$gl_cv_func_getcwd_path_max" != yes \ + || test $gl_abort_bug = yes; then + REPLACE_GETCWD=1 + fi ]) # Prerequisites of lib/getcwd.c, when full replacement is in effect. -- In memoriam George Moscone <http://en.wikipedia.org/wiki/George_Moscone>