bug-coreutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: address@hidden: Re: dired fails when ls exits with >0]


From: Paul Eggert
Subject: Re: address@hidden: Re: dired fails when ls exits with >0]
Date: Thu, 09 Dec 2004 09:56:07 -0800
User-agent: Gnus/5.1006 (Gnus v5.10.6) Emacs/21.3 (gnu/linux)

Jim Meyering <address@hidden> writes:

> I'm glad to see that you made it handle readdir/EOVERFLOW, too.

Me too.  I think there are other readdir/EOVERFLOW problems elsewhere
in coreutils, but one fix at a time.

I did see a couple of other EXIT_FAILUREs that needed to be turned
into LS_FAILURES, and (after getting confused with the names) I
renamed LS_MINOR_FAILURE to LS_MINOR_PROBLEM.  So I installed this
slightly changed patch instead:

2004-12-09  Paul Eggert  <address@hidden>

        ls now exits with status 1 on minor problems, 2 if serious trouble.

        * NEWS: Document this.
        * doc/coreutils.texi (ls invocation): Document new "ls" exit status.
        * src/ls.c (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.
        * tests/help-version: ls and variants now exit with status 2
        on serious trouble.

Index: NEWS
===================================================================
RCS file: /fetish/cu/NEWS,v
retrieving revision 1.253
retrieving revision 1.254
diff -p -u -r1.253 -r1.254
--- NEWS        8 Dec 2004 22:38:10 -0000       1.253
+++ NEWS        9 Dec 2004 17:49:45 -0000       1.254
@@ -239,6 +239,8 @@ GNU coreutils NEWS                      
   echo -e '\xHH' now outputs a byte whose hexadecimal value is HH,
   for compatibility with bash.
 
+  ls now exits with status 1 on minor problems, 2 if serious trouble.
+
   ls has a new --hide=PATTERN option that behaves like
   --ignore=PATTERN, except that it is overridden by -a or -A.
   This can be useful for aliases, e.g., if lh is an alias for
Index: doc/coreutils.texi
===================================================================
RCS file: /fetish/cu/doc/coreutils.texi,v
retrieving revision 1.230
retrieving revision 1.231
diff -p -u -r1.230 -r1.231
--- doc/coreutils.texi  4 Dec 2004 14:23:48 -0000       1.230
+++ doc/coreutils.texi  9 Dec 2004 17:50:54 -0000       1.231
@@ -5290,7 +5290,14 @@ within each section, options are listed 
 The division of options into the subsections is not absolute, since some
 options affect more than one aspect of @command{ls}'s operation.
 
address@hidden
address@hidden exit status of @command{ls}
+Exit status:
+
address@hidden
+0 success
+1 minor problems (e.g., a file could not be found)
+2 serious trouble (e.g., memory exhausted)
address@hidden display
 
 Also see @ref{Common options}.
 
Index: src/ls.c
===================================================================
RCS file: /fetish/cu/src/ls.c,v
retrieving revision 1.370
retrieving revision 1.371
diff -p -u -r1.370 -r1.371
--- src/ls.c    2 Dec 2004 07:47:14 -0000       1.370
+++ src/ls.c    9 Dec 2004 17:48:57 -0000       1.371
@@ -682,6 +682,17 @@ static sig_atomic_t volatile stop_signal
 
 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 
   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 
        {
          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 
       /* 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 (errno)
+    {
+      error (0, errno, _("reading directory %s"), quotearg_colon (name));
+      exit_status = LS_FAILURE;
     }
 
-  if (dirp == NULL || CLOSEDIR (dirp))
+  if (CLOSEDIR (dirp) != 0)
     {
       error (0, errno, _("reading directory %s"), quotearg_colon (name));
-      exit_status = EXIT_FAILURE;
+      exit_status = LS_FAILURE;
       /* Don't return; print whatever we got.  */
     }
 
@@ -2511,7 +2526,8 @@ gobble_file (const char *name, enum file
       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, str
     {
       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 
 --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);
Index: tests/help-version
===================================================================
RCS file: /fetish/cu/tests/help-version,v
retrieving revision 1.14
retrieving revision 1.15
diff -p -u -r1.14 -r1.15
--- tests/help-version  17 Feb 2004 16:05:34 -0000      1.14
+++ tests/help-version  9 Dec 2004 17:49:18 -0000       1.15
@@ -10,6 +10,9 @@ expected_failure_status_tty=3
 expected_failure_status_sort=2
 expected_failure_status_expr=3
 expected_failure_status_lbracket=2
+expected_failure_status_dir=2
+expected_failure_status_ls=2
+expected_failure_status_vdir=2
 
 case "$all_programs" in
   *groups*)




reply via email to

[Prev in Thread] Current Thread [Next in Thread]