bug-coreutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: ia64 GNU/Linux pwd-long test failure in CVS coreutils


From: Jim Meyering
Subject: Re: ia64 GNU/Linux pwd-long test failure in CVS coreutils
Date: Sun, 18 Jun 2006 23:55:07 +0200

Jim Meyering <address@hidden> wrote:
> address@hidden (Bob Proulx) wrote:
> ...
>> One thing that I am a little worried about by the test is the initial
>> mkdir call.
>>
>>       if (mkdir (dir_name, S_IRWXU) < 0 || chdir (dir_name) < 0)
>>         {
>>           fail = 3; /* Unable to construct deep hierarchy.  */
>>
>> That also fails if remnants of the test structure are left behind by a
>> previous failed run of the test or if there is not enough permission
>> to create a directory and other things like that.  Not sure that is
>> really bad but my paranoia causes me to suggest that the first mkdir
>> be checked individually to separate out the two different types of
>> failures.  And then it always tries to rmdir regardless in that case.
>> Check this out.
>
> Right.
> In the driver .m4/shell code I'll be careful to make sure things
> are cleaned up both before and after.

Here's the change that should make coreutils work around
that glibc/ia64-specific getcwd bug.  Just checked in on the trunk.

2006-06-18  Jim Meyering  <address@hidden>

        Test for a bug that causes glibc's getcwd to suffer a failed assertion.
        * getcwd-abort-bug.m4 (gl_FUNC_GETCWD_ABORT_BUG): New file and macro.
        * getcwd.m4 (gl_FUNC_GETCWD): If we detect support for getcwd_null,
        also check for glibc-2.4's abort-inducing bug.

Index: getcwd.m4
===================================================================
RCS file: /fetish/cu/m4/getcwd.m4,v
retrieving revision 1.10
diff -u -p -r1.10 getcwd.m4
--- getcwd.m4   22 Sep 2005 06:05:39 -0000      1.10
+++ getcwd.m4   18 Jun 2006 20:16:16 -0000
@@ -1,6 +1,6 @@
 # getcwd.m4 - check for working getcwd that is compatible with glibc
 
-# Copyright (C) 2001, 2003, 2004, 2005 Free Software Foundation, Inc.
+# Copyright (C) 2001, 2003, 2004, 2005, 2006 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.
@@ -40,12 +40,15 @@ AC_DEFUN([gl_FUNC_GETCWD],
 [
   AC_REQUIRE([gl_FUNC_GETCWD_NULL])
 
+  gl_abort_bug=no
   case $gl_cv_func_getcwd_null in
-  yes) gl_FUNC_GETCWD_PATH_MAX;;
+  yes)
+    gl_FUNC_GETCWD_PATH_MAX
+    gl_FUNC_GETCWD_ABORT_BUG([gl_abort_bug=yes]);;
   esac
 
-  case $gl_cv_func_getcwd_null,$gl_cv_func_getcwd_path_max in
-  yes,yes) ;;
+  case $gl_cv_func_getcwd_null,$gl_cv_func_getcwd_path_max,$gl_abort_bug in
+  yes,yes,no) ;;
   *)
     AC_LIBOBJ([getcwd])
     AC_DEFINE([__GETCWD_PREFIX], [[rpl_]],
Index: getcwd-abort-bug.m4
===================================================================
RCS file: getcwd-abort-bug.m4
diff -N getcwd-abort-bug.m4
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ getcwd-abort-bug.m4 18 Jun 2006 20:02:21 -0000
@@ -0,0 +1,106 @@
+#serial 1
+# 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 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.
+
+# From Jim Meyering
+
+# gl_FUNC_GETCWD_ABORT_BUG([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
+AC_DEFUN([gl_FUNC_GETCWD_ABORT_BUG],
+[
+  AC_CHECK_DECLS_ONCE(getcwd)
+  AC_CHECK_FUNCS(getpagesize)
+  AC_CACHE_CHECK([whether getcwd aborts when 4k < cwd_length < 16k],
+    gl_cv_func_getcwd_abort_bug,
+    [# Remove any remnants of a previous test.
+     rm -rf confdir-14B---
+     # Arrange for deletion of the temporary directory this test creates.
+     ac_clean_files="$ac_clean_files confdir-14B---"
+     AC_RUN_IFELSE(
+       [AC_LANG_SOURCE(
+         [[
+#include <stdlib.h>
+#include <unistd.h>
+#include <limits.h>
+#include <string.h>
+#include <sys/stat.h>
+
+/* Don't get link errors because mkdir is redefined to rpl_mkdir.  */
+#undef mkdir
+
+#ifndef S_IRWXU
+# define S_IRWXU 0700
+#endif
+
+/* FIXME: skip the run-test altogether on systems without getpagesize.  */
+#if ! HAVE_GETPAGESIZE
+# define getpagesize() 0
+#endif
+
+/* This size is chosen to be larger than PATH_MAX (4k), yet smaller than
+   the 16kB pagesize on ia64 linux.  Those conditions make the code below
+   trigger a bug in glibc's getcwd implementation before 2.4.90-10.  */
+#define TARGET_LEN (5 * 1024)
+
+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)
+    return 0;
+
+  cwd = getcwd (NULL, 0);
+  if (cwd == NULL)
+    return 0;
+
+  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 (mkdir (dir_name, S_IRWXU) < 0 || chdir (dir_name) < 0)
+       {
+         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);
+
+  /* Call rmdir first, in case the above chdir failed.  */
+  rmdir (dir_name);
+  while (0 < d--)
+    {
+      if (chdir ("..") < 0)
+       break;
+      rmdir (dir_name);
+    }
+
+  return 0;
+}
+          ]])],
+    [gl_cv_func_getcwd_abort_bug=no],
+    [gl_cv_func_getcwd_abort_bug=yes],
+    [gl_cv_func_getcwd_abort_bug=yes])
+  ])
+  AS_IF([test $gl_cv_func_getcwd_abort_bug = yes], [$1], [$2])
+])




reply via email to

[Prev in Thread] Current Thread [Next in Thread]