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