bug-gnulib
[Top][All Lists]
Advanced

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

[PATCH 1/3] getcwd: consolidate m4 files


From: Eric Blake
Subject: [PATCH 1/3] getcwd: consolidate m4 files
Date: Mon, 25 Apr 2011 16:28:25 -0600

It was confusing having 1 out of 3 known getcwd problems checked
in place, and the other two in separate files.

* m4/getcwd-abort-bug.m4, m4/getcwd-path-max.m4: Delete, moving
contents...
* m4/getcwd.m4: Here.
* modules/getcwd (Files): Reflect the motion.

Signed-off-by: Eric Blake <address@hidden>
---
 ChangeLog              |    8 ++
 m4/getcwd-abort-bug.m4 |  106 ------------------
 m4/getcwd-path-max.m4  |  188 -------------------------------
 m4/getcwd.m4           |  285 +++++++++++++++++++++++++++++++++++++++++++++++-
 modules/getcwd         |    2 -
 5 files changed, 292 insertions(+), 297 deletions(-)
 delete mode 100644 m4/getcwd-abort-bug.m4
 delete mode 100644 m4/getcwd-path-max.m4

diff --git a/ChangeLog b/ChangeLog
index 65ed4a0..f113c64 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2011-04-25  Eric Blake  <address@hidden>
+
+       getcwd: consolidate m4 files
+       * m4/getcwd-abort-bug.m4, m4/getcwd-path-max.m4: Delete, moving
+       contents...
+       * m4/getcwd.m4: Here.
+       * modules/getcwd (Files): Reflect the motion.
+
 2011-04-25  Jim Meyering  <address@hidden>

        maint.mk: makefile_at_at_check extend and clean up
diff --git a/m4/getcwd-abort-bug.m4 b/m4/getcwd-abort-bug.m4
deleted file mode 100644
index 21be828..0000000
--- a/m4/getcwd-abort-bug.m4
+++ /dev/null
@@ -1,106 +0,0 @@
-# serial 2
-# 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.
-# 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])
-])
diff --git a/m4/getcwd-path-max.m4 b/m4/getcwd-path-max.m4
deleted file mode 100644
index 2ab2645..0000000
--- a/m4/getcwd-path-max.m4
+++ /dev/null
@@ -1,188 +0,0 @@
-# serial 15
-# Check for several getcwd bugs with long file names.
-# If so, arrange to compile the wrapper function.
-
-# This is necessary for at least GNU libc on linux-2.4.19 and 2.4.20.
-# I've heard that this is due to a Linux kernel bug, and that it has
-# been fixed between 2.4.21-pre3 and 2.4.21-pre4.  */
-
-# Copyright (C) 2003-2007, 2009-2011 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
-
-AC_DEFUN([gl_FUNC_GETCWD_PATH_MAX],
-[
-  AC_CHECK_DECLS_ONCE([getcwd])
-  AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
-  AC_CACHE_CHECK([whether getcwd handles long file names properly],
-    gl_cv_func_getcwd_path_max,
-    [# Arrange for deletion of the temporary directory this test creates.
-     ac_clean_files="$ac_clean_files confdir3"
-     AC_RUN_IFELSE(
-       [AC_LANG_SOURCE(
-          [[
-#include <errno.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <limits.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <fcntl.h>
-
-#ifndef AT_FDCWD
-# define AT_FDCWD 0
-#endif
-#ifdef ENAMETOOLONG
-# define is_ENAMETOOLONG(x) ((x) == ENAMETOOLONG)
-#else
-# define is_ENAMETOOLONG(x) 0
-#endif
-
-/* Don't get link errors because mkdir is redefined to rpl_mkdir.  */
-#undef mkdir
-
-#ifndef S_IRWXU
-# define S_IRWXU 0700
-#endif
-
-/* The length of this name must be 8.  */
-#define DIR_NAME "confdir3"
-#define DIR_NAME_LEN 8
-#define DIR_NAME_SIZE (DIR_NAME_LEN + 1)
-
-/* The length of "../".  */
-#define DOTDOTSLASH_LEN 3
-
-/* Leftover bytes in the buffer, to work around library or OS bugs.  */
-#define BUF_SLOP 20
-
-int
-main ()
-{
-#ifndef PATH_MAX
-  /* The Hurd doesn't define this, so getcwd can't exhibit the bug --
-     at least not on a local file system.  And if we were to start worrying
-     about remote file systems, we'd have to enable the wrapper function
-     all of the time, just to be safe.  That's not worth the cost.  */
-  exit (0);
-#elif ((INT_MAX / (DIR_NAME_SIZE / DOTDOTSLASH_LEN + 1) \
-        - DIR_NAME_SIZE - BUF_SLOP) \
-       <= PATH_MAX)
-  /* FIXME: Assuming there's a system for which this is true,
-     this should be done in a compile test.  */
-  exit (0);
-#else
-  char buf[PATH_MAX * (DIR_NAME_SIZE / DOTDOTSLASH_LEN + 1)
-           + DIR_NAME_SIZE + BUF_SLOP];
-  char *cwd = getcwd (buf, PATH_MAX);
-  size_t initial_cwd_len;
-  size_t cwd_len;
-  int fail = 0;
-  size_t n_chdirs = 0;
-
-  if (cwd == NULL)
-    exit (10);
-
-  cwd_len = initial_cwd_len = strlen (cwd);
-
-  while (1)
-    {
-      size_t dotdot_max = PATH_MAX * (DIR_NAME_SIZE / DOTDOTSLASH_LEN);
-      char *c = NULL;
-
-      cwd_len += DIR_NAME_SIZE;
-      /* If mkdir or chdir fails, it could be that this system cannot create
-         any file with an absolute name longer than PATH_MAX, such as cygwin.
-         If so, leave fail as 0, because the current working directory can't
-         be too long for getcwd if it can't even be created.  For other
-         errors, be pessimistic and consider that as a failure, too.  */
-      if (mkdir (DIR_NAME, S_IRWXU) < 0 || chdir (DIR_NAME) < 0)
-        {
-          if (! (errno == ERANGE || is_ENAMETOOLONG (errno)))
-            fail = 20;
-          break;
-        }
-
-      if (PATH_MAX <= cwd_len && cwd_len < PATH_MAX + DIR_NAME_SIZE)
-        {
-          c = getcwd (buf, PATH_MAX);
-          if (!c && errno == ENOENT)
-            {
-              fail = 11;
-              break;
-            }
-          if (c || ! (errno == ERANGE || is_ENAMETOOLONG (errno)))
-            {
-              fail = 21;
-              break;
-            }
-        }
-
-      if (dotdot_max <= cwd_len - initial_cwd_len)
-        {
-          if (dotdot_max + DIR_NAME_SIZE < cwd_len - initial_cwd_len)
-            break;
-          c = getcwd (buf, cwd_len + 1);
-          if (!c)
-            {
-              if (! (errno == ERANGE || errno == ENOENT
-                     || is_ENAMETOOLONG (errno)))
-                {
-                  fail = 22;
-                  break;
-                }
-              if (AT_FDCWD || errno == ERANGE || errno == ENOENT)
-                {
-                  fail = 12;
-                  break;
-                }
-            }
-        }
-
-      if (c && strlen (c) != cwd_len)
-        {
-          fail = 23;
-          break;
-        }
-      ++n_chdirs;
-    }
-
-  /* Leaving behind such a deep directory is not polite.
-     So clean up here, right away, even though the driving
-     shell script would also clean up.  */
-  {
-    size_t i;
-
-    /* Try rmdir first, in case the chdir failed.  */
-    rmdir (DIR_NAME);
-    for (i = 0; i <= n_chdirs; i++)
-      {
-        if (chdir ("..") < 0)
-          break;
-        if (rmdir (DIR_NAME) != 0)
-          break;
-      }
-  }
-
-  exit (fail);
-#endif
-}
-          ]])],
-    [gl_cv_func_getcwd_path_max=yes],
-    [case $? in
-     10|11|12) gl_cv_func_getcwd_path_max='no, but it is partly working';;
-     *) gl_cv_func_getcwd_path_max=no;;
-     esac],
-    [gl_cv_func_getcwd_path_max=no])
-  ])
-  case $gl_cv_func_getcwd_path_max in
-  no,*)
-    AC_DEFINE([HAVE_PARTLY_WORKING_GETCWD], [1],
-      [Define to 1 if getcwd works, except it sometimes fails when it 
shouldn't,
-       setting errno to ERANGE, ENAMETOOLONG, or ENOENT.]);;
-  esac
-])
diff --git a/m4/getcwd.m4 b/m4/getcwd.m4
index 7098056..5016a1b 100644
--- a/m4/getcwd.m4
+++ b/m4/getcwd.m4
@@ -6,7 +6,7 @@
 # with or without modifications, as long as this notice is preserved.

 # Written by Paul Eggert.
-# serial 3
+# serial 4

 AC_DEFUN([gl_FUNC_GETCWD_NULL],
   [
@@ -52,6 +52,289 @@ AC_DEFUN([gl_FUNC_GETCWD_NULL],
         ]])])
 ])

+
+# 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.
+# 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])
+])
+
+# Check for several getcwd bugs with long file names.
+# If so, arrange to compile the wrapper function.
+# This is necessary for at least GNU libc on linux-2.4.19 and 2.4.20.
+# I've heard that this is due to a Linux kernel bug, and that it has
+# been fixed between 2.4.21-pre3 and 2.4.21-pre4.
+# From Jim Meyering
+AC_DEFUN([gl_FUNC_GETCWD_PATH_MAX],
+[
+  AC_CHECK_DECLS_ONCE([getcwd])
+  AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
+  AC_CACHE_CHECK([whether getcwd handles long file names properly],
+    gl_cv_func_getcwd_path_max,
+    [# Arrange for deletion of the temporary directory this test creates.
+     ac_clean_files="$ac_clean_files confdir3"
+     AC_RUN_IFELSE(
+       [AC_LANG_SOURCE(
+          [[
+#include <errno.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <limits.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <fcntl.h>
+
+#ifndef AT_FDCWD
+# define AT_FDCWD 0
+#endif
+#ifdef ENAMETOOLONG
+# define is_ENAMETOOLONG(x) ((x) == ENAMETOOLONG)
+#else
+# define is_ENAMETOOLONG(x) 0
+#endif
+
+/* Don't get link errors because mkdir is redefined to rpl_mkdir.  */
+#undef mkdir
+
+#ifndef S_IRWXU
+# define S_IRWXU 0700
+#endif
+
+/* The length of this name must be 8.  */
+#define DIR_NAME "confdir3"
+#define DIR_NAME_LEN 8
+#define DIR_NAME_SIZE (DIR_NAME_LEN + 1)
+
+/* The length of "../".  */
+#define DOTDOTSLASH_LEN 3
+
+/* Leftover bytes in the buffer, to work around library or OS bugs.  */
+#define BUF_SLOP 20
+
+int
+main ()
+{
+#ifndef PATH_MAX
+  /* The Hurd doesn't define this, so getcwd can't exhibit the bug --
+     at least not on a local file system.  And if we were to start worrying
+     about remote file systems, we'd have to enable the wrapper function
+     all of the time, just to be safe.  That's not worth the cost.  */
+  exit (0);
+#elif ((INT_MAX / (DIR_NAME_SIZE / DOTDOTSLASH_LEN + 1) \
+        - DIR_NAME_SIZE - BUF_SLOP) \
+       <= PATH_MAX)
+  /* FIXME: Assuming there's a system for which this is true,
+     this should be done in a compile test.  */
+  exit (0);
+#else
+  char buf[PATH_MAX * (DIR_NAME_SIZE / DOTDOTSLASH_LEN + 1)
+           + DIR_NAME_SIZE + BUF_SLOP];
+  char *cwd = getcwd (buf, PATH_MAX);
+  size_t initial_cwd_len;
+  size_t cwd_len;
+  int fail = 0;
+  size_t n_chdirs = 0;
+
+  if (cwd == NULL)
+    exit (10);
+
+  cwd_len = initial_cwd_len = strlen (cwd);
+
+  while (1)
+    {
+      size_t dotdot_max = PATH_MAX * (DIR_NAME_SIZE / DOTDOTSLASH_LEN);
+      char *c = NULL;
+
+      cwd_len += DIR_NAME_SIZE;
+      /* If mkdir or chdir fails, it could be that this system cannot create
+         any file with an absolute name longer than PATH_MAX, such as cygwin.
+         If so, leave fail as 0, because the current working directory can't
+         be too long for getcwd if it can't even be created.  For other
+         errors, be pessimistic and consider that as a failure, too.  */
+      if (mkdir (DIR_NAME, S_IRWXU) < 0 || chdir (DIR_NAME) < 0)
+        {
+          if (! (errno == ERANGE || is_ENAMETOOLONG (errno)))
+            fail = 20;
+          break;
+        }
+
+      if (PATH_MAX <= cwd_len && cwd_len < PATH_MAX + DIR_NAME_SIZE)
+        {
+          c = getcwd (buf, PATH_MAX);
+          if (!c && errno == ENOENT)
+            {
+              fail = 11;
+              break;
+            }
+          if (c || ! (errno == ERANGE || is_ENAMETOOLONG (errno)))
+            {
+              fail = 21;
+              break;
+            }
+        }
+
+      if (dotdot_max <= cwd_len - initial_cwd_len)
+        {
+          if (dotdot_max + DIR_NAME_SIZE < cwd_len - initial_cwd_len)
+            break;
+          c = getcwd (buf, cwd_len + 1);
+          if (!c)
+            {
+              if (! (errno == ERANGE || errno == ENOENT
+                     || is_ENAMETOOLONG (errno)))
+                {
+                  fail = 22;
+                  break;
+                }
+              if (AT_FDCWD || errno == ERANGE || errno == ENOENT)
+                {
+                  fail = 12;
+                  break;
+                }
+            }
+        }
+
+      if (c && strlen (c) != cwd_len)
+        {
+          fail = 23;
+          break;
+        }
+      ++n_chdirs;
+    }
+
+  /* Leaving behind such a deep directory is not polite.
+     So clean up here, right away, even though the driving
+     shell script would also clean up.  */
+  {
+    size_t i;
+
+    /* Try rmdir first, in case the chdir failed.  */
+    rmdir (DIR_NAME);
+    for (i = 0; i <= n_chdirs; i++)
+      {
+        if (chdir ("..") < 0)
+          break;
+        if (rmdir (DIR_NAME) != 0)
+          break;
+      }
+  }
+
+  exit (fail);
+#endif
+}
+          ]])],
+    [gl_cv_func_getcwd_path_max=yes],
+    [case $? in
+     10|11|12) gl_cv_func_getcwd_path_max='no, but it is partly working';;
+     *) gl_cv_func_getcwd_path_max=no;;
+     esac],
+    [gl_cv_func_getcwd_path_max=no])
+  ])
+  case $gl_cv_func_getcwd_path_max in
+  no,*)
+    AC_DEFINE([HAVE_PARTLY_WORKING_GETCWD], [1],
+      [Define to 1 if getcwd works, except it sometimes fails when it 
shouldn't,
+       setting errno to ERANGE, ENAMETOOLONG, or ENOENT.]);;
+  esac
+])
+
+
+dnl Check for all known getcwd bugs; useful for a program likely to be
+dnl executed from an arbitrary location, by augmenting native getcwd.
 AC_DEFUN([gl_FUNC_GETCWD],
 [
   AC_REQUIRE([gl_UNISTD_H_DEFAULTS])
diff --git a/modules/getcwd b/modules/getcwd
index 108f14b..de27c9a 100644
--- a/modules/getcwd
+++ b/modules/getcwd
@@ -3,8 +3,6 @@ Return the current working directory.

 Files:
 lib/getcwd.c
-m4/getcwd-abort-bug.m4
-m4/getcwd-path-max.m4
 m4/getcwd.m4

 Depends-on:
-- 
1.7.4.4




reply via email to

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