diff options
author | Jim Meyering <jim@meyering.net> | 2002-08-29 10:16:00 +0000 |
---|---|---|
committer | Jim Meyering <jim@meyering.net> | 2002-08-29 10:16:00 +0000 |
commit | 515f184462e354affdf6b7eb8cff80ca27e7aea4 (patch) | |
tree | cfe492f9574b0180958bbcbf8a60f4238c8b0e2d /src | |
parent | 609231e3fa7bbf252dafd34cf15c12e8d86bfeec (diff) | |
download | coreutils-515f184462e354affdf6b7eb8cff80ca27e7aea4.tar.xz |
(print_dir): Detect and diagnose readdir failures.
On some systems (at least EMC Celerra and Solaris5.8),
this appears to be necessary.
(print_dir): Rename local variable: reading -> dirp.
Diffstat (limited to 'src')
-rw-r--r-- | src/ls.c | 44 |
1 files changed, 32 insertions, 12 deletions
@@ -2077,23 +2077,43 @@ print_dir (const char *name, const char *realname) clear_files (); - while ((next = readdir (dirp)) != 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 (dirp)) + 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. */ } |