*** empty log message ***
[findutils.git] / m4 / readdir.m4
blobd851b0fe38344dafd6badb02bfe7a3ab9aee287b
1 #serial 3
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.
13 dnl Written by Jim Meyering.
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"
25   AC_TRY_RUN(
26 [#   include <stdio.h>
27 #   include <sys/types.h>
28 #   if HAVE_STRING_H
29 #    include <string.h>
30 #   endif
32 #   ifdef HAVE_DIRENT_H
33 #    include <dirent.h>
34 #    define NLENGTH(direct) (strlen((direct)->d_name))
35 #   else /* not HAVE_DIRENT_H */
36 #    define dirent direct
37 #    define NLENGTH(direct) ((direct)->d_namlen)
38 #    ifdef HAVE_SYS_NDIR_H
39 #     include <sys/ndir.h>
40 #    endif /* HAVE_SYS_NDIR_H */
41 #    ifdef HAVE_SYS_DIR_H
42 #     include <sys/dir.h>
43 #    endif /* HAVE_SYS_DIR_H */
44 #    ifdef HAVE_NDIR_H
45 #     include <ndir.h>
46 #    endif /* HAVE_NDIR_H */
47 #   endif /* HAVE_DIRENT_H */
49 #   define DOT_OR_DOTDOT(Basename) \
50      (Basename[0] == '.' && (Basename[1] == '\0' \
51                              || (Basename[1] == '.' && Basename[2] == '\0')))
53     static void
54     create_300_file_dir (const char *dir)
55     {
56       int i;
58       if (mkdir (dir, 0700))
59         abort ();
60       if (chdir (dir))
61         abort ();
63       for (i = 0; i < 300; i++)
64         {
65           char file_name[4];
66           FILE *out;
68           sprintf (file_name, "%03d", i);
69           out = fopen (file_name, "w");
70           if (!out)
71             abort ();
72           if (fclose (out) == EOF)
73             abort ();
74         }
76       if (chdir (".."))
77         abort ();
78     }
80     static void
81     remove_dir (const char *dir)
82     {
83       DIR *dirp;
85       if (chdir (dir))
86         abort ();
88       dirp = opendir (".");
89       if (dirp == NULL)
90         abort ();
92       while (1)
93         {
94           struct dirent *dp = readdir (dirp);
95           if (dp == NULL)
96             break;
98           if (DOT_OR_DOTDOT (dp->d_name))
99             continue;
101           if (unlink (dp->d_name))
102             abort ();
103         }
104       closedir (dirp);
106       if (chdir (".."))
107         abort ();
109       if (rmdir (dir))
110         exit (1);
111     }
113     int
114     main ()
115     {
116       const char *dir = "conf-dir";
117       create_300_file_dir (dir);
118       remove_dir (dir);
119       exit (0);
120     }],
121   jm_cv_func_working_readdir=yes,
122   jm_cv_func_working_readdir=no,
123   jm_cv_func_working_readdir=no)])
125   if test $jm_cv_func_working_readdir = yes; then
126     AC_DEFINE_UNQUOTED(HAVE_WORKING_READDIR, 1,
127 [Define if readdir is found to work properly in some unusual cases. ])
128   fi