X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=m4%2Fgetcwd-abort-bug.m4;h=9b3b5636b9a175ea4aab9dc3ee6b121a53320892;hb=daa269958ad8d50ef8154ccb65e58acaf7a6dd99;hp=21be828b622f4d63ea1b0b805e1b6947f01e16b1;hpb=1a44d77d50f4fb37c0410eed04b82303624ea2ec;p=debian%2Ftar diff --git a/m4/getcwd-abort-bug.m4 b/m4/getcwd-abort-bug.m4 index 21be828b..9b3b5636 100644 --- a/m4/getcwd-abort-bug.m4 +++ b/m4/getcwd-abort-bug.m4 @@ -1,9 +1,9 @@ -# serial 2 +# 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. -# Copyright (C) 2006, 2009-2011 Free Software Foundation, Inc. +# Copyright (C) 2006, 2009-2013 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -14,6 +14,8 @@ AC_DEFUN([gl_FUNC_GETCWD_ABORT_BUG], [ AC_CHECK_DECLS_ONCE([getcwd]) + AC_CHECK_HEADERS_ONCE([unistd.h]) + AC_REQUIRE([gl_PATHMAX_SNIPPET_PREREQ]) AC_CHECK_FUNCS([getpagesize]) AC_CACHE_CHECK([whether getcwd aborts when 4k < cwd_length < 16k], gl_cv_func_getcwd_abort_bug, @@ -21,15 +23,21 @@ AC_DEFUN([gl_FUNC_GETCWD_ABORT_BUG], rm -rf confdir-14B--- # Arrange for deletion of the temporary directory this test creates. ac_clean_files="$ac_clean_files confdir-14B---" + dnl Please keep this in sync with tests/test-getcwd.c. AC_RUN_IFELSE( [AC_LANG_SOURCE( [[ #include -#include -#include +#if HAVE_UNISTD_H +# include +#else /* on Windows with MSVC */ +# include +#endif #include #include +]gl_PATHMAX_SNIPPET[ + /* Don't get link errors because mkdir is redefined to rpl_mkdir. */ #undef mkdir @@ -50,56 +58,81 @@ AC_DEFUN([gl_FUNC_GETCWD_ABORT_BUG], int main () { - char const *dir_name = "confdir-14B---"; char *cwd; size_t initial_cwd_len; int fail = 0; - size_t desired_depth; - size_t d; /* The bug is triggered when PATH_MAX < getpagesize (), so skip - this relative expensive and invasive test if that's not true. */ - if (getpagesize () <= PATH_MAX) + this relatively expensive and invasive test if that's not true. */ +#ifdef PATH_MAX + int bug_possible = PATH_MAX < getpagesize (); +#else + int bug_possible = 0; +#endif + if (! bug_possible) return 0; cwd = getcwd (NULL, 0); if (cwd == NULL) - return 0; + return 2; initial_cwd_len = strlen (cwd); free (cwd); - desired_depth = ((TARGET_LEN - 1 - initial_cwd_len) - / (1 + strlen (dir_name))); - for (d = 0; d < desired_depth; d++) + + if (1) { - if (mkdir (dir_name, S_IRWXU) < 0 || chdir (dir_name) < 0) + static char const dir_name[] = "confdir-14B---"; + size_t desired_depth = ((TARGET_LEN - 1 - initial_cwd_len) + / sizeof dir_name); + size_t d; + for (d = 0; d < desired_depth; d++) { - fail = 3; /* Unable to construct deep hierarchy. */ - break; + if (mkdir (dir_name, S_IRWXU) < 0 || chdir (dir_name) < 0) + { + if (! (errno == ERANGE || errno == ENAMETOOLONG + || errno == ENOENT)) + fail = 3; /* Unable to construct deep hierarchy. */ + break; + } } - } - /* If libc has the bug in question, this invocation of getcwd - results in a failed assertion. */ - cwd = getcwd (NULL, 0); - if (cwd == NULL) - fail = 4; /* getcwd failed. This is ok, and expected. */ - free (cwd); + /* If libc has the bug in question, this invocation of getcwd + results in a failed assertion. */ + cwd = getcwd (NULL, 0); + if (cwd == NULL) + fail = 4; /* getcwd didn't assert, but it failed for a long name + where the answer could have been learned. */ + free (cwd); - /* Call rmdir first, in case the above chdir failed. */ - rmdir (dir_name); - while (0 < d--) - { - if (chdir ("..") < 0) - break; + /* Call rmdir first, in case the above chdir failed. */ rmdir (dir_name); + while (0 < d--) + { + if (chdir ("..") < 0) + { + fail = 5; + break; + } + rmdir (dir_name); + } } - return 0; + return fail; } ]])], [gl_cv_func_getcwd_abort_bug=no], - [gl_cv_func_getcwd_abort_bug=yes], + [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])