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
bindtextdomain (PACKAGE, LOCALEDIR);
textdomain (PACKAGE);
+ initialize_exit_failure (LS_FAILURE);
atexit (close_stdout);
#define N_ENTRIES(Array) (sizeof Array / sizeof *(Array))
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;
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;
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
default:
- usage (EXIT_FAILURE);
+ usage (LS_FAILURE);
}
}
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';
}
if (!dirp)
{
error (0, errno, "%s", quotearg_colon (name));
- exit_status = EXIT_FAILURE;
+ exit_status = LS_FAILURE;
return;
}
{
error (0, errno, _("cannot determine device and inode of %s"),
quotearg_colon (name));
- exit_status = EXIT_FAILURE;
+ exit_status = LS_FAILURE;
return;
}
/* 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. */
}
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;
}
{
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;
}
}
{
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;
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);
}