1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
|
#serial 1
dnl SunOS's readdir is broken in such a way that rm.c has to add extra code
dnl to test whether a NULL return value really means there are no more files
dnl in the directory.
dnl
dnl Detect the problem by creating a directory containing 300 files (254 not
dnl counting . and .. is the minimum) and see if a loop doing `readdir; unlink'
dnl removes all of them.
dnl
dnl Define HAVE_WORKING_READDIR if readdir does *not* have this problem.
dnl Written by Jim Meyering.
AC_DEFUN(jm_FUNC_READDIR,
[dnl
AC_REQUIRE([AC_HEADER_DIRENT])
AC_CHECK_HEADERS(string.h)
AC_CACHE_CHECK([for working readdir], jm_cv_func_working_readdir,
[dnl
# Arrange for deletion of the temporary directory this test creates, in
# case the test itself fails to delete everything -- as happens on Sunos.
ac_clean_files="$ac_clean_files conf-dir"
AC_TRY_RUN(
changequote(<<, >>)dnl
<<
# include <stdio.h>
# include <sys/types.h>
# if HAVE_STRING_H
# include <string.h>
# endif
# ifdef HAVE_DIRENT_H
# include <dirent.h>
# define NLENGTH(direct) (strlen((direct)->d_name))
# else /* not HAVE_DIRENT_H */
# define dirent direct
# define NLENGTH(direct) ((direct)->d_namlen)
# ifdef HAVE_SYS_NDIR_H
# include <sys/ndir.h>
# endif /* HAVE_SYS_NDIR_H */
# ifdef HAVE_SYS_DIR_H
# include <sys/dir.h>
# endif /* HAVE_SYS_DIR_H */
# ifdef HAVE_NDIR_H
# include <ndir.h>
# endif /* HAVE_NDIR_H */
# endif /* HAVE_DIRENT_H */
# define DOT_OR_DOTDOT(Basename) \
(Basename[0] == '.' && (Basename[1] == '\0' \
|| (Basename[1] == '.' && Basename[2] == '\0')))
static void
create_300_file_dir (const char *dir)
{
int i;
if (mkdir (dir, 0700))
abort ();
if (chdir (dir))
abort ();
for (i = 0; i < 300; i++)
{
char file_name[4];
FILE *out;
sprintf (file_name, "%03d", i);
out = fopen (file_name, "w");
if (!out)
abort ();
if (fclose (out) == EOF)
abort ();
}
if (chdir (".."))
abort ();
}
static void
remove_dir (const char *dir)
{
DIR *dirp;
if (chdir (dir))
abort ();
dirp = opendir (".");
if (dirp == NULL)
abort ();
while (1)
{
struct dirent *dp = readdir (dirp);
if (dp == NULL)
break;
if (DOT_OR_DOTDOT (dp->d_name))
continue;
if (unlink (dp->d_name))
abort ();
}
closedir (dirp);
if (chdir (".."))
abort ();
if (rmdir (dir))
exit (1);
}
int
main ()
{
const char *dir = "conf-dir";
create_300_file_dir (dir);
remove_dir (dir);
exit (0);
}
>>,
changequote([, ])dnl
jm_cv_func_working_readdir=yes,
jm_cv_func_working_readdir=no,
jm_cv_func_working_readdir=no)])
if test x = y; then
dnl This code is deliberately never run via ./configure.
dnl FIXME: this is a gross hack to make autoheader put an entry
dnl for this HAVE_-prefixed symbol in config.h.in.
AC_CHECK_FUNCS(WORKING_READDIR)
fi
if test $jm_cv_func_working_readdir = yes; then
ac_kludge=HAVE_WORKING_READDIR
AC_DEFINE_UNQUOTED($ac_kludge)
fi
])
|