updated from automake
[coreutils.git] / m4 / getcwd-path-max.m4
bloba6f5c08c67f5255170faa60ee0b9800430f38b89
1 #serial 4
2 # Check whether getcwd has the bug that it succeeds for a working directory
3 # longer than PATH_MAX, yet returns a truncated directory name.
4 # If so, arrange to compile the wrapper function.
6 # This is necessary for at least GNU libc on linux-2.4.19 and 2.4.20.
7 # I've heard that this is due to a Linux kernel bug, and that it has
8 # been fixed between 2.4.21-pre3 and 2.4.21-pre4.  */
10 # From Jim Meyering
12 AC_DEFUN([GL_FUNC_GETCWD_PATH_MAX],
14   AC_CHECK_DECLS([getcwd])
15   AC_CACHE_CHECK([whether getcwd properly handles paths longer than PATH_MAX],
16                  gl_cv_func_getcwd_vs_path_max,
17   [
18   # Arrange for deletion of the temporary directory this test creates.
19   ac_clean_files="$ac_clean_files confdir3"
20   AC_RUN_IFELSE([AC_LANG_SOURCE([[
21 #include <stdlib.h>
22 #include <unistd.h>
23 #include <string.h>
24 #include <limits.h>
25 #include <sys/stat.h>
26 #include <sys/types.h>
28 /* Don't get link errors because mkdir is redefined to rpl_mkdir.  */
29 #undef mkdir
31 #ifndef CHAR_BIT
32 # define CHAR_BIT 8
33 #endif
35 /* The extra casts work around common compiler bugs.  */
36 #define TYPE_SIGNED(t) (! ((t) 0 < (t) -1))
37 /* The outer cast is needed to work around a bug in Cray C 5.0.3.0.
38    It is necessary at least when t == time_t.  */
39 #define TYPE_MINIMUM(t) ((t) (TYPE_SIGNED (t) \
40                               ? ~ (t) 0 << (sizeof (t) * CHAR_BIT - 1) : (t) 0))
41 #define TYPE_MAXIMUM(t) ((t) (~ (t) 0 - TYPE_MINIMUM (t)))
43 #ifndef INT_MAX
44 # define INT_MAX TYPE_MAXIMUM (int)
45 #endif
47 /* The length of this name must be 8.  */
48 #define DIR_NAME "confdir3"
50 int
51 main ()
53 #ifndef PATH_MAX
54   /* The Hurd doesn't define this, so getcwd can't exhibit the bug --
55      at least not on a local file system.  And if we were to start worrying
56      about remote file systems, we'd have to enable the wrapper function
57      all of the time, just to be safe.  That's not worth the cost.  */
58   exit (0);
59 #elif INT_MAX - 9 <= PATH_MAX
60   /* The '9', above, comes from strlen (DIR_NAME) + 1.  */
61   /* FIXME: Assuming there's a system for which this is true,
62      this should be done in a compile test.  */
63   exit (0);
64 #else
65   char buf[PATH_MAX + 20];
66   char *cwd = getcwd (buf, PATH_MAX);
67   size_t cwd_len;
68   int fail = 0;
69   size_t n_chdirs = 0;
71   if (cwd == NULL)
72     exit (1);
74   cwd_len = strlen (cwd);
76   while (1)
77     {
78       char *c;
79       size_t len;
81       cwd_len += 1 + strlen (DIR_NAME);
82       /* If mkdir or chdir fails, be pessimistic and consider that
83          as a failure, too.  */
84       if (mkdir (DIR_NAME, 0700) < 0 || chdir (DIR_NAME) < 0)
85         {
86           fail = 1;
87           break;
88         }
89       if ((c = getcwd (buf, PATH_MAX)) == NULL)
90         {
91           /* This allows any failure to indicate there is no bug.
92              FIXME: check errno?  */
93           break;
94         }
95       if ((len = strlen (c)) != cwd_len)
96         {
97           fail = 1;
98           break;
99         }
100       ++n_chdirs;
101       if (PATH_MAX < len)
102         break;
103     }
105   /* Leaving behind such a deep directory is not polite.
106      So clean up here, right away, even though the driving
107      shell script would also clean up.  */
108   {
109     size_t i;
111     /* Unlink first, in case the chdir failed.  */
112     unlink (DIR_NAME);
113     for (i = 0; i <= n_chdirs; i++)
114       {
115         if (chdir ("..") < 0)
116           break;
117         rmdir (DIR_NAME);
118       }
119   }
121   exit (fail);
122 #endif
124   ]])],
125        [gl_cv_func_getcwd_vs_path_max=yes],
126        [gl_cv_func_getcwd_vs_path_max=no],
127        [gl_cv_func_getcwd_vs_path_max=no])])
129   if test $gl_cv_func_getcwd_vs_path_max = yes; then
130     AC_LIBOBJ(getcwd)
131     AC_DEFINE(getcwd, rpl_getcwd,
132       [Define to rpl_getcwd if the wrapper function should be used.])
133   fi