1#serial 4
2
3dnl SunOS's readdir is broken in such a way that rm.c has to add extra code
4dnl to test whether a NULL return value really means there are no more files
5dnl in the directory.
6dnl
7dnl Detect the problem by creating a directory containing 300 files (254 not
8dnl counting . and .. is the minimum) and see if a loop doing `readdir; unlink'
9dnl removes all of them.
10dnl
11dnl Define HAVE_WORKING_READDIR if readdir does *not* have this problem.
12
13dnl Written by Jim Meyering.
14
15AC_DEFUN([jm_FUNC_READDIR],
16[dnl
17AC_REQUIRE([AC_HEADER_DIRENT])
18AC_CHECK_HEADERS(string.h)
19AC_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[#   include <stdio.h>
27#   include <sys/types.h>
28#   if HAVE_STRING_H
29#    include <string.h>
30#   endif
31
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 */
48
49#   define DOT_OR_DOTDOT(Basename) \
50     (Basename[0] == '.' && (Basename[1] == '\0' \
51			     || (Basename[1] == '.' && Basename[2] == '\0')))
52
53/* Don't try to use replacement mkdir; it wouldn't resolve at link time.  */
54#   undef mkdir
55
56    static void
57    create_300_file_dir (const char *dir)
58    {
59      int i;
60
61      if (mkdir (dir, 0700))
62	abort ();
63      if (chdir (dir))
64	abort ();
65
66      for (i = 0; i < 300; i++)
67	{
68	  char file_name[4];
69	  FILE *out;
70
71	  sprintf (file_name, "%03d", i);
72	  out = fopen (file_name, "w");
73	  if (!out)
74	    abort ();
75	  if (fclose (out) == EOF)
76	    abort ();
77	}
78
79      if (chdir (".."))
80	abort ();
81    }
82
83    static void
84    remove_dir (const char *dir)
85    {
86      DIR *dirp;
87
88      if (chdir (dir))
89	abort ();
90
91      dirp = opendir (".");
92      if (dirp == NULL)
93	abort ();
94
95      while (1)
96	{
97	  struct dirent *dp = readdir (dirp);
98	  if (dp == NULL)
99	    break;
100
101	  if (DOT_OR_DOTDOT (dp->d_name))
102	    continue;
103
104	  if (unlink (dp->d_name))
105	    abort ();
106	}
107      closedir (dirp);
108
109      if (chdir (".."))
110	abort ();
111
112      if (rmdir (dir))
113	exit (1);
114    }
115
116    int
117    main ()
118    {
119      const char *dir = "conf-dir";
120      create_300_file_dir (dir);
121      remove_dir (dir);
122      exit (0);
123    }],
124  jm_cv_func_working_readdir=yes,
125  jm_cv_func_working_readdir=no,
126  jm_cv_func_working_readdir=no)])
127
128  if test $jm_cv_func_working_readdir = yes; then
129    AC_DEFINE(HAVE_WORKING_READDIR, 1,
130[Define if readdir is found to work properly in some unusual cases. ])
131  fi
132])
133