Tag
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
])