summaryrefslogtreecommitdiff
path: root/src/ls.c
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2004-12-09 17:48:57 +0000
committerPaul Eggert <eggert@cs.ucla.edu>2004-12-09 17:48:57 +0000
commit310ef64346e1e181d6d83bc158a0824ed14a929c (patch)
tree792a3b76bffee90a7f20d6251b632decaa5cb7e0 /src/ls.c
parent73eca3827eec0f9d9fb99f83c434bc606d0b0e45 (diff)
downloadcoreutils-310ef64346e1e181d6d83bc158a0824ed14a929c.tar.xz
(LS_MINOR_PROBLEM, LS_FAILURE): New constants.
All uses of EXIT_FAILURE replaced with LS_FAILURE, unless specified below. (main): Initialize exit failure to LS_FAILURE. (print_dir, gobble_file, get_link_name, xstrcoll): Set exit status to LS_MINOR_PROBLEM if the failure is minor. (print_dir): Do not give up on entire directory merely because readdir returns EOVERFLOW. (usage): Explain exit status.
Diffstat (limited to 'src/ls.c')
-rw-r--r--src/ls.c92
1 files changed, 57 insertions, 35 deletions
diff --git a/src/ls.c b/src/ls.c
index fca28f2e3..6adfefaf6 100644
--- a/src/ls.c
+++ b/src/ls.c
@@ -682,6 +682,17 @@ static sig_atomic_t volatile stop_signal_count;
static int exit_status;
+/* Exit statuses. */
+enum
+ {
+ /* "ls" had a minor problem (e.g., it could not stat a directory
+ entry). */
+ LS_MINOR_PROBLEM = 1,
+
+ /* "ls" had more serious trouble. */
+ LS_FAILURE = 2
+ };
+
/* For long options that have no equivalent short option, use a
non-character as a pseudo short option, starting with CHAR_MAX + 1. */
enum
@@ -1095,6 +1106,7 @@ main (int argc, char **argv)
bindtextdomain (PACKAGE, LOCALEDIR);
textdomain (PACKAGE);
+ initialize_exit_failure (LS_FAILURE);
atexit (close_stdout);
#define N_ENTRIES(Array) (sizeof Array / sizeof *(Array))
@@ -1553,7 +1565,7 @@ decode_switches (int argc, char **argv)
unsigned long int tmp_ulong;
if (xstrtoul (optarg, NULL, 0, &tmp_ulong, NULL) != LONGINT_OK
|| ! (0 < tmp_ulong && tmp_ulong <= SIZE_MAX))
- error (EXIT_FAILURE, 0, _("invalid line width: %s"),
+ error (LS_FAILURE, 0, _("invalid line width: %s"),
quotearg (optarg));
line_length = tmp_ulong;
break;
@@ -1627,7 +1639,7 @@ decode_switches (int argc, char **argv)
unsigned long int tmp_ulong;
if (xstrtoul (optarg, NULL, 0, &tmp_ulong, NULL) != LONGINT_OK
|| SIZE_MAX < tmp_ulong)
- error (EXIT_FAILURE, 0, _("invalid tab size: %s"),
+ error (LS_FAILURE, 0, _("invalid tab size: %s"),
quotearg (optarg));
tabsize = tmp_ulong;
break;
@@ -1740,7 +1752,7 @@ decode_switches (int argc, char **argv)
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
default:
- usage (EXIT_FAILURE);
+ usage (LS_FAILURE);
}
}
@@ -1804,7 +1816,7 @@ decode_switches (int argc, char **argv)
else
{
if (strchr (p1 + 1, '\n'))
- error (EXIT_FAILURE, 0, _("invalid time style format %s"),
+ error (LS_FAILURE, 0, _("invalid time style format %s"),
quote (p0));
*p1++ = '\0';
}
@@ -2217,7 +2229,7 @@ print_dir (const char *name, const char *realname)
if (!dirp)
{
error (0, errno, "%s", quotearg_colon (name));
- exit_status = EXIT_FAILURE;
+ exit_status = LS_FAILURE;
return;
}
@@ -2233,7 +2245,7 @@ print_dir (const char *name, const char *realname)
{
error (0, errno, _("cannot determine device and inode of %s"),
quotearg_colon (name));
- exit_status = EXIT_FAILURE;
+ exit_status = LS_FAILURE;
return;
}
@@ -2259,43 +2271,46 @@ print_dir (const char *name, const char *realname)
/* 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)
+ next = readdir (dirp);
+ if (next)
{
- if (errno)
+ if (! file_ignored (next->d_name))
{
- /* Save/restore errno across closedir call. */
- int e = errno;
- closedir (dirp);
- errno = e;
+ enum filetype type = unknown;
- /* Arrange to give a diagnostic after exiting this loop. */
- dirp = NULL;
+#if HAVE_STRUCT_DIRENT_D_TYPE
+ if (next->d_type == DT_BLK
+ || next->d_type == DT_CHR
+ || next->d_type == DT_DIR
+ || next->d_type == DT_FIFO
+ || next->d_type == DT_LNK
+ || next->d_type == DT_REG
+ || next->d_type == DT_SOCK)
+ type = next->d_type;
+#endif
+ total_blocks += gobble_file (next->d_name, type, false, name);
}
- break;
}
-
- if (! file_ignored (next->d_name))
+ else if (errno == EOVERFLOW)
{
- enum filetype type = unknown;
-
-#if HAVE_STRUCT_DIRENT_D_TYPE
- if (next->d_type == DT_BLK
- || next->d_type == DT_CHR
- || next->d_type == DT_DIR
- || next->d_type == DT_FIFO
- || next->d_type == DT_LNK
- || next->d_type == DT_REG
- || next->d_type == DT_SOCK)
- type = next->d_type;
-#endif
- total_blocks += gobble_file (next->d_name, type, false, name);
+ error (0, errno, _("reading directory %s"), quotearg_colon (name));
+ if (exit_status == EXIT_SUCCESS)
+ exit_status = LS_MINOR_PROBLEM;
}
+ else
+ break;
}
- if (dirp == NULL || CLOSEDIR (dirp))
+ if (errno)
{
error (0, errno, _("reading directory %s"), quotearg_colon (name));
- exit_status = EXIT_FAILURE;
+ exit_status = LS_FAILURE;
+ }
+
+ if (CLOSEDIR (dirp) != 0)
+ {
+ error (0, errno, _("reading directory %s"), quotearg_colon (name));
+ exit_status = LS_FAILURE;
/* Don't return; print whatever we got. */
}
@@ -2511,7 +2526,8 @@ gobble_file (const char *name, enum filetype type, bool explicit_arg,
if (err < 0)
{
error (0, errno, "%s", quotearg_colon (path));
- exit_status = EXIT_FAILURE;
+ if (exit_status == EXIT_SUCCESS)
+ exit_status = LS_MINOR_PROBLEM;
return 0;
}
@@ -2667,7 +2683,8 @@ get_link_name (const char *filename, struct fileinfo *f)
{
error (0, errno, _("cannot read symbolic link %s"),
quotearg_colon (filename));
- exit_status = EXIT_FAILURE;
+ if (exit_status == EXIT_SUCCESS)
+ exit_status = LS_MINOR_PROBLEM;
}
}
@@ -2784,7 +2801,8 @@ xstrcoll (char const *a, char const *b)
{
error (0, errno, _("cannot compare file names %s and %s"),
quote_n (0, a), quote_n (1, b));
- exit_status = EXIT_FAILURE;
+ if (exit_status == EXIT_SUCCESS)
+ exit_status = LS_MINOR_PROBLEM;
longjmp (failed_strcoll, 1);
}
return diff;
@@ -4155,6 +4173,10 @@ optional WHEN argument is equivalent to using --color=always. With\n\
--color=auto, color codes are output only if standard output is connected\n\
to a terminal (tty).\n\
"), stdout);
+ fputs (_("\
+\n\
+Exit status is 0 if OK, 1 if minor problems, 2 if serious trouble.\n\
+"), stdout);
printf (_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT);
}
exit (status);