Ok. The Solaris5.8 man page for readdir suggests the same thing, so I've changed remove.c and ls.c to check for readdir failures:
* src/remove.c (remove_cwd_entries): Use closedir (not CLOSEDIR) when ignoring any return value. * src/remove.c (remove_cwd_entries): Detect and diagnose readdir failures. On some systems (at least EMC Celerra and Solaris5.8), this appears to be necessary. (is_empty_dir): Likewise. Also, always close directory handle. * src/ls.c (print_dir): Likewise. (print_dir): Rename local variable: reading -> dirp. Reported by Mike Coleman. There remain three files in lib/ that need similar changes. Thanks again for the report and follow-up. Index: ls.c =================================================================== RCS file: /fetish/cu/src/ls.c,v retrieving revision 1.304 retrieving revision 1.306 diff -u -p -u -r1.304 -r1.306 --- ls.c 8 Jul 2002 09:12:48 -0000 1.304 +++ ls.c 29 Aug 2002 10:16:00 -0000 1.306 @@ -2030,14 +2030,14 @@ queue_directory (const char *name, const static void print_dir (const char *name, const char *realname) { - register DIR *reading; + register DIR *dirp; register struct dirent *next; register uintmax_t total_blocks = 0; static int first = 1; errno = 0; - reading = opendir (name); - if (!reading) + dirp = opendir (name); + if (!dirp) { error (0, errno, "%s", quotearg_colon (name)); exit_status = 1; @@ -2047,7 +2047,7 @@ print_dir (const char *name, const char if (LOOP_DETECT) { struct stat dir_stat; - int fd = dirfd (reading); + int fd = dirfd (dirp); /* If dirfd failed, endure the overhead of using stat. */ if ((0 <= fd @@ -2077,23 +2077,43 @@ print_dir (const char *name, const char clear_files (); - while ((next = readdir (reading)) != NULL) - if (file_interesting (next)) - { - enum filetype type = unknown; + while (1) + { + /* Set errno to zero so we can distinguish between a readdir failure + and when readdir simply finds that there are no more entries. */ + errno = 0; + if ((next = readdir (dirp)) == NULL) + { + if (errno) + { + /* Save/restore errno across closedir call. */ + int e = errno; + closedir (dirp); + errno = e; + + /* Arrange to give a diagnostic after exiting this loop. */ + dirp = NULL; + } + break; + } + + if (file_interesting (next)) + { + enum filetype type = unknown; #if HAVE_STRUCT_DIRENT_D_TYPE - if (next->d_type == DT_DIR || next->d_type == DT_CHR - || next->d_type == DT_BLK || next->d_type == DT_SOCK - || next->d_type == DT_FIFO) - type = next->d_type; + if (next->d_type == DT_DIR || next->d_type == DT_CHR + || next->d_type == DT_BLK || next->d_type == DT_SOCK + || next->d_type == DT_FIFO) + type = next->d_type; #endif - total_blocks += gobble_file (next->d_name, type, 0, name); - } + total_blocks += gobble_file (next->d_name, type, 0, name); + } + } - if (CLOSEDIR (reading)) + if (dirp == NULL || CLOSEDIR (dirp)) { - error (0, errno, "%s", quotearg_colon (name)); + error (0, errno, _("reading directory %s"), quotearg_colon (name)); exit_status = 1; /* Don't return; print whatever we got. */ } Index: remove.c =================================================================== RCS file: /fetish/cu/src/remove.c,v retrieving revision 1.59 retrieving revision 1.63 diff -u -p -u -r1.59 -r1.63 --- remove.c 22 Jul 2002 06:59:26 -0000 1.59 +++ remove.c 29 Aug 2002 10:42:12 -0000 1.63 @@ -522,19 +522,30 @@ is_empty_dir (char const *dir) { DIR *dirp = opendir (dir); if (dirp == NULL) - return false; + { + closedir (dirp); + return false; + } while (1) { - struct dirent *dp = readdir (dirp); + struct dirent *dp; const char *f; + errno = 0; + dp = readdir (dirp); if (dp == NULL) - return true; + { + closedir (dirp); + return errno == 0 ? true : false; + } f = dp->d_name; if ( ! DOT_OR_DOTDOT (f)) - return false; + { + closedir (dirp); + return false; + } } } @@ -810,12 +821,27 @@ remove_cwd_entries (char **subdir, struc while (1) { - struct dirent *dp = readdir (dirp); + struct dirent *dp; enum RM_status tmp_status; const char *f; - if (dp == NULL) - break; + /* Set errno to zero so we can distinguish between a readdir failure + and when readdir simply finds that there are no more entries. */ + errno = 0; + if ((dp = readdir (dirp)) == NULL) + { + if (errno) + { + /* Save/restore errno across closedir call. */ + int e = errno; + closedir (dirp); + errno = e; + + /* Arrange to give a diagnostic after exiting this loop. */ + dirp = NULL; + } + break; + } f = dp->d_name; if (DOT_OR_DOTDOT (f)) @@ -871,7 +897,13 @@ remove_cwd_entries (char **subdir, struc break; } - closedir (dirp); + if (dirp == NULL || CLOSEDIR (dirp) != 0) + { + /* Note that this diagnostic serves for both readdir + and closedir failures. */ + error (0, errno, _("reading directory %s"), quote (full_filename ("."))); + status = RM_ERROR; + } return status; } _______________________________________________ Bug-fileutils mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/bug-fileutils