changeset 37515:969445ba6a67

getcwd: fix test failure on OS X 10.9 * m4/getcwd-path-max.m4: Avoid the replacement if it won't be effective due to the PATH_MAX limitation of lstat(). (gl_cv_func_getcwd_path_max): Adjust to indicate this case. * m4/getcwd.m4 (gl_FUNC_GETCWD): Define HAVE_GETCWD_SHORTER for this case for use in tests, and also exclude this case when setting REPLACE_GETCWD. * tests/test-getcwd.c (test_long_name): Restrict the tested path length so that lstat() will not be passed a path greater than PATH_MAX. Also key a test condition on HAVE_OPENAT_SUPPORT rather than AT_FDCWD, since the latter is set unconditionally since Sep 2009 in commit 52c658e9.
author Pádraig Brady <P@draigBrady.com>
date Tue, 16 Dec 2014 02:35:19 +0000
parents 433c904ce7eb
children c17209aca9db
files ChangeLog m4/getcwd-path-max.m4 m4/getcwd.m4 tests/test-getcwd.c
diffstat 4 files changed, 42 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Sun Dec 14 20:32:54 2014 +0000
+++ b/ChangeLog	Tue Dec 16 02:35:19 2014 +0000
@@ -1,3 +1,19 @@
+2014-12-16  Pádraig Brady  <P@draigBrady.com>
+
+	getcwd: fix test failure on OS X 10.9
+	* m4/getcwd-path-max.m4: Avoid the replacement if it
+	won't be effective due to the PATH_MAX limitation of lstat().
+	(gl_cv_func_getcwd_path_max): Adjust to indicate this case.
+	* m4/getcwd.m4 (gl_FUNC_GETCWD): Define HAVE_GETCWD_SHORTER
+	for this case for use in tests, and also exclude this
+	case when setting REPLACE_GETCWD.
+	* tests/test-getcwd.c (test_long_name): Restrict the
+	tested path length so that lstat() will not be passed
+	a path greater than PATH_MAX.
+	Also key a test condition on HAVE_OPENAT_SUPPORT rather
+	than AT_FDCWD, since the latter is set unconditionally
+	since Sep 2009 in commit 52c658e9.
+
 2014-12-14  Tim Rühsen  <tim.ruehsen@gmx.de>
 
 	parse-datetime: avoid a compiler warning with byacc (trivial)
--- a/m4/getcwd-path-max.m4	Sun Dec 14 20:32:54 2014 +0000
+++ b/m4/getcwd-path-max.m4	Tue Dec 16 02:35:19 2014 +0000
@@ -122,6 +122,8 @@
 
       if (PATH_MAX <= cwd_len && cwd_len < PATH_MAX + DIR_NAME_SIZE)
         {
+          struct stat sb;
+
           c = getcwd (buf, PATH_MAX);
           if (!c && errno == ENOENT)
             {
@@ -138,6 +140,16 @@
               fail = 21;
               break;
             }
+
+          /* Our replacement needs to be able to stat() long ../../paths,
+             so generate a path larger than PATH_MAX to check,
+             avoiding the replacement if we can't stat().  */
+          c = getcwd (buf, cwd_len + 1);
+          if (c && !AT_FDCWD && stat (c, &sb) != 0 && is_ENAMETOOLONG (errno))
+            {
+              fail = 32;
+              break;
+            }
         }
 
       if (dotdot_max <= cwd_len - initial_cwd_len)
@@ -194,6 +206,7 @@
     [case $? in
      10|11|12) gl_cv_func_getcwd_path_max='no, but it is partly working';;
      31) gl_cv_func_getcwd_path_max='no, it has the AIX bug';;
+     32) gl_cv_func_getcwd_path_max='yes, but with shorter paths';;
      *) gl_cv_func_getcwd_path_max=no;;
      esac],
     [case "$host_os" in
--- a/m4/getcwd.m4	Sun Dec 14 20:32:54 2014 +0000
+++ b/m4/getcwd.m4	Tue Dec 16 02:35:19 2014 +0000
@@ -136,11 +136,16 @@
         [Define to 1 if getcwd works, except it sometimes fails when it
          shouldn't, setting errno to ERANGE, ENAMETOOLONG, or ENOENT.])
       ;;
+    "yes, but with shorter paths")
+      AC_DEFINE([HAVE_GETCWD_SHORTER], [1],
+        [Define to 1 if getcwd works, but with shorter paths
+         than is generally tested with the replacement.])
+      ;;
   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 \
+     || { case "$gl_cv_func_getcwd_path_max" in *yes*) false;; *) true;; esac; } \
      || test $gl_abort_bug = yes; then
     REPLACE_GETCWD=1
   fi
--- a/tests/test-getcwd.c	Sun Dec 14 20:32:54 2014 +0000
+++ b/tests/test-getcwd.c	Tue Dec 16 02:35:19 2014 +0000
@@ -153,7 +153,13 @@
 
   while (1)
     {
+# ifdef HAVE_GETCWD_SHORTER
+      /* On OS/X <= 10.9 for example, we're restricted to shorter paths
+         as lstat() doesn't support more than PATH_MAX.  */
+      size_t dotdot_max = PATH_MAX * 2;
+# else
       size_t dotdot_max = PATH_MAX * (DIR_NAME_SIZE / DOTDOTSLASH_LEN);
+# endif
       char *c = NULL;
 
       cwd_len += DIR_NAME_SIZE;
@@ -202,7 +208,7 @@
                   fail = 6;
                   break;
                 }
-              if (AT_FDCWD || errno == ERANGE || errno == ENOENT)
+              if (HAVE_OPENAT_SUPPORT || errno == ERANGE || errno == ENOENT)
                 {
                   fail = 7;
                   break;