summaryrefslogtreecommitdiff
path: root/src/ls.c
diff options
context:
space:
mode:
authorJim Meyering <jim@meyering.net>2002-08-29 10:16:00 +0000
committerJim Meyering <jim@meyering.net>2002-08-29 10:16:00 +0000
commit515f184462e354affdf6b7eb8cff80ca27e7aea4 (patch)
treecfe492f9574b0180958bbcbf8a60f4238c8b0e2d /src/ls.c
parent609231e3fa7bbf252dafd34cf15c12e8d86bfeec (diff)
downloadcoreutils-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/ls.c')
-rw-r--r--src/ls.c44
1 files changed, 32 insertions, 12 deletions
diff --git a/src/ls.c b/src/ls.c
index 7b2dd50f1..16f22c7c5 100644
--- a/src/ls.c
+++ b/src/ls.c
@@ -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. */
}