1 | #serial 1
|
---|
2 | # Determine whether getcwd aborts when the length of the working directory
|
---|
3 | # name is unusually large. Any length between 4k and 16k trigger the bug
|
---|
4 | # when using glibc-2.4.90-9 or older.
|
---|
5 |
|
---|
6 | # Copyright (C) 2006 Free Software Foundation, Inc.
|
---|
7 | # This file is free software; the Free Software Foundation
|
---|
8 | # gives unlimited permission to copy and/or distribute it,
|
---|
9 | # with or without modifications, as long as this notice is preserved.
|
---|
10 |
|
---|
11 | # From Jim Meyering
|
---|
12 |
|
---|
13 | # gl_FUNC_GETCWD_ABORT_BUG([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
|
---|
14 | AC_DEFUN([gl_FUNC_GETCWD_ABORT_BUG],
|
---|
15 | [
|
---|
16 | AC_CHECK_DECLS_ONCE(getcwd)
|
---|
17 | AC_CHECK_FUNCS(getpagesize)
|
---|
18 | AC_CACHE_CHECK([whether getcwd aborts when 4k < cwd_length < 16k],
|
---|
19 | gl_cv_func_getcwd_abort_bug,
|
---|
20 | [# Remove any remnants of a previous test.
|
---|
21 | rm -rf confdir-14B---
|
---|
22 | # Arrange for deletion of the temporary directory this test creates.
|
---|
23 | ac_clean_files="$ac_clean_files confdir-14B---"
|
---|
24 | AC_RUN_IFELSE(
|
---|
25 | [AC_LANG_SOURCE(
|
---|
26 | [[
|
---|
27 | #include <stdlib.h>
|
---|
28 | #include <unistd.h>
|
---|
29 | #include <limits.h>
|
---|
30 | #include <string.h>
|
---|
31 | #include <sys/stat.h>
|
---|
32 |
|
---|
33 | /* Don't get link errors because mkdir is redefined to rpl_mkdir. */
|
---|
34 | #undef mkdir
|
---|
35 |
|
---|
36 | #ifndef S_IRWXU
|
---|
37 | # define S_IRWXU 0700
|
---|
38 | #endif
|
---|
39 |
|
---|
40 | /* FIXME: skip the run-test altogether on systems without getpagesize. */
|
---|
41 | #if ! HAVE_GETPAGESIZE
|
---|
42 | # define getpagesize() 0
|
---|
43 | #endif
|
---|
44 |
|
---|
45 | /* This size is chosen to be larger than PATH_MAX (4k), yet smaller than
|
---|
46 | the 16kB pagesize on ia64 linux. Those conditions make the code below
|
---|
47 | trigger a bug in glibc's getcwd implementation before 2.4.90-10. */
|
---|
48 | #define TARGET_LEN (5 * 1024)
|
---|
49 |
|
---|
50 | int
|
---|
51 | main ()
|
---|
52 | {
|
---|
53 | char const *dir_name = "confdir-14B---";
|
---|
54 | char *cwd;
|
---|
55 | size_t initial_cwd_len;
|
---|
56 | int fail = 0;
|
---|
57 | size_t desired_depth;
|
---|
58 | size_t d;
|
---|
59 |
|
---|
60 | /* The bug is triggered when PATH_MAX < getpagesize (), so skip
|
---|
61 | this relative expensive and invasive test if that's not true. */
|
---|
62 | if (getpagesize () <= PATH_MAX)
|
---|
63 | return 0;
|
---|
64 |
|
---|
65 | cwd = getcwd (NULL, 0);
|
---|
66 | if (cwd == NULL)
|
---|
67 | return 0;
|
---|
68 |
|
---|
69 | initial_cwd_len = strlen (cwd);
|
---|
70 | free (cwd);
|
---|
71 | desired_depth = ((TARGET_LEN - 1 - initial_cwd_len)
|
---|
72 | / (1 + strlen (dir_name)));
|
---|
73 | for (d = 0; d < desired_depth; d++)
|
---|
74 | {
|
---|
75 | if (mkdir (dir_name, S_IRWXU) < 0 || chdir (dir_name) < 0)
|
---|
76 | {
|
---|
77 | fail = 3; /* Unable to construct deep hierarchy. */
|
---|
78 | break;
|
---|
79 | }
|
---|
80 | }
|
---|
81 |
|
---|
82 | /* If libc has the bug in question, this invocation of getcwd
|
---|
83 | results in a failed assertion. */
|
---|
84 | cwd = getcwd (NULL, 0);
|
---|
85 | if (cwd == NULL)
|
---|
86 | fail = 4; /* getcwd failed. This is ok, and expected. */
|
---|
87 | free (cwd);
|
---|
88 |
|
---|
89 | /* Call rmdir first, in case the above chdir failed. */
|
---|
90 | rmdir (dir_name);
|
---|
91 | while (0 < d--)
|
---|
92 | {
|
---|
93 | if (chdir ("..") < 0)
|
---|
94 | break;
|
---|
95 | rmdir (dir_name);
|
---|
96 | }
|
---|
97 |
|
---|
98 | return 0;
|
---|
99 | }
|
---|
100 | ]])],
|
---|
101 | [gl_cv_func_getcwd_abort_bug=no],
|
---|
102 | [gl_cv_func_getcwd_abort_bug=yes],
|
---|
103 | [gl_cv_func_getcwd_abort_bug=yes])
|
---|
104 | ])
|
---|
105 | AS_IF([test $gl_cv_func_getcwd_abort_bug = yes], [$1], [$2])
|
---|
106 | ])
|
---|