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