bug-tar
[Top][All Lists]
Advanced

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

[Bug-tar] tar fixes to exit with more-correct status on failures


From: Paul Eggert
Subject: [Bug-tar] tar fixes to exit with more-correct status on failures
Date: Tue, 07 Feb 2006 15:56:40 -0800
User-agent: Gnus/5.1007 (Gnus v5.10.7) Emacs/21.4 (gnu/linux)

In several places 'tar' and 'rmt' exit with the wrong status.
Most of these involve write failures.  For example:

$ (sleep 1; trap '' PIPE; tar --version; echo $? >&2) | :
0

'tar' didn't report the write error due to writing on the empty pipe.
The correct behavior is something like this:

$ (sleep 1; trap '' PIPE; src/tar --version; echo $? >&2) | :
src/tar: write error: Broken pipe
2

There are also problems with memory allocation failures and
argument-processing errors.

I installed this patch to fix the errors that I found in this area.

2006-02-07  Paul Eggert  <address@hidden>

        * gnulib.modules: Add closeout, exitfial.
        * lib/.cvsignore: Add __fpending.c, __fpending.h, closeout.c,
        closeout.h.
        * src/buffer.c: Incluse closeout.h.
        (_open_archive): Use freopen rather than fopen, so
        that stdlis is always either stdout or stderr.  Use
        close_stdout_set_file_name to report its name.
        * src/tar.c: Include closeout.h and exitfail.h.
        (parse_opt, usage): Call close_stdout as appropriate, to check for
        write errors.
        (decode_options): Exit with status TAREXIT_FAILURE, not 1.
        (main): Set exit_failure, to exit with proper status on memory
        allocation failure and the like.
        Use close_stdout rather than rolling our own test.
        * paxutils/gnulib.modules: Add closeout.
        * paxutils/rmt/rmt.c: Include closeout.h.
        (main, usage): Use close_stdout to report write errors properly.

Index: gnulib.modules
===================================================================
RCS file: /cvsroot/tar/tar/gnulib.modules,v
retrieving revision 1.7
diff -p -b -u -r1.7 gnulib.modules
--- gnulib.modules      7 Feb 2006 22:18:36 -0000       1.7
+++ gnulib.modules      7 Feb 2006 23:49:29 -0000
@@ -5,9 +5,11 @@ alloca
 argmatch
 argp
 backupfile
+closeout
 dirname
 error
 exclude
+exitfail
 fileblocks
 fnmatch-gnu
 ftruncate
Index: lib/.cvsignore
===================================================================
RCS file: /cvsroot/tar/tar/lib/.cvsignore,v
retrieving revision 1.30
diff -p -b -u -r1.30 .cvsignore
--- lib/.cvsignore      7 Feb 2006 22:18:36 -0000       1.30
+++ lib/.cvsignore      7 Feb 2006 23:49:29 -0000
@@ -1,4 +1,8 @@
 .deps
+__fpending.c
+__fpending.h
+closeout.c
+closeout.h
 Makefile
 Makefile.am
 Makefile.in
Index: src/buffer.c
===================================================================
RCS file: /cvsroot/tar/tar/src/buffer.c,v
retrieving revision 1.92
diff -p -b -u -r1.92 buffer.c
--- src/buffer.c        9 Dec 2005 10:04:26 -0000       1.92
+++ src/buffer.c        7 Feb 2006 23:49:29 -0000
@@ -1,7 +1,7 @@
 /* Buffer management for tar.
 
    Copyright (C) 1988, 1992, 1993, 1994, 1996, 1997, 1999, 2000, 2001,
-   2003, 2004, 2005 Free Software Foundation, Inc.
+   2003, 2004, 2005, 2006 Free Software Foundation, Inc.
 
    Written by John Gilmore, on 1985-08-25.
 
@@ -23,6 +23,7 @@
 
 #include <signal.h>
 
+#include <closeout.h>
 #include <fnmatch.h>
 #include <human.h>
 #include <quotearg.h>
@@ -383,9 +384,10 @@ _open_archive (enum access_mode wanted_a
 
   if (index_file_name)
     {
-      stdlis = fopen (index_file_name, "w");
+      stdlis = freopen (index_file_name, "w", stdout);
       if (! stdlis)
        open_error (index_file_name);
+      close_stdout_set_file_name (index_file_name);
     }
   else
     stdlis = to_stdout_option ? stderr : stdout;
@@ -1623,4 +1625,3 @@ open_archive (enum access_mode wanted_ac
       break;
     }
 }
-
Index: src/tar.c
===================================================================
RCS file: /cvsroot/tar/tar/src/tar.c,v
retrieving revision 1.138
diff -p -b -u -r1.138 tar.c
--- src/tar.c   7 Feb 2006 22:18:36 -0000       1.138
+++ src/tar.c   7 Feb 2006 23:49:29 -0000
@@ -37,6 +37,8 @@
 #include "common.h"
 
 #include <argmatch.h>
+#include <closeout.h>
+#include <exitfail.h>
 #include <getdate.h>
 #include <localedir.h>
 #include <rmt.h>
@@ -1441,7 +1443,8 @@ parse_opt (int key, char *arg, struct ar
 
     case SHOW_DEFAULTS_OPTION:
       show_default_settings (stdout);
-      exit(0);
+      close_stdout ();
+      exit (0);
 
     case STRIP_COMPONENTS_OPTION:
       {
@@ -1605,16 +1608,18 @@ parse_opt (int key, char *arg, struct ar
       fprintf (state->out_stream, "\n");
       fprintf (state->out_stream, _("Report bugs to %s.\n"),
               argp_program_bug_address);
+      close_stdout ();
       exit (0);
 
     case USAGE_OPTION:
-      argp_state_help (state, state->out_stream,
-                      ARGP_HELP_USAGE | ARGP_HELP_EXIT_OK);
-      break;
+      argp_state_help (state, state->out_stream, ARGP_HELP_USAGE);
+      close_stdout ();
+      exit (0);
 
     case VERSION_OPTION:
       version_etc (state->out_stream, "tar", PACKAGE_NAME, VERSION,
                   "John Gilmore", "Jay Fenlason", (char *) NULL);
+      close_stdout ();
       exit (0);
 
     case HANG_OPTION:
@@ -1643,6 +1648,7 @@ void
 usage (int status)
 {
   argp_help (&argp, stderr, ARGP_HELP_SEE, (char*) program_name);
+  close_stdout ();
   exit (status);
 }
 
@@ -1753,7 +1759,7 @@ decode_options (int argc, char **argv)
 
   if (argp_parse (&argp, argc, argv, ARGP_IN_ORDER|ARGP_NO_HELP,
                  &index, &args))
-    exit (1);
+    exit (TAREXIT_FAILURE);
 
 
   /* Special handling for 'o' option:
@@ -2003,6 +2009,7 @@ main (int argc, char **argv)
   bindtextdomain (PACKAGE, LOCALEDIR);
   textdomain (PACKAGE);
 
+  exit_failure = TAREXIT_FAILURE;
   exit_status = TAREXIT_SUCCESS;
   filename_terminator = '\n';
   set_quoting_style (0, DEFAULT_QUOTING_STYLE);
@@ -2089,8 +2096,9 @@ main (int argc, char **argv)
   free (archive_name_array);
   name_term ();
 
-  if (stdlis != stderr && (ferror (stdlis) || fclose (stdlis) != 0))
-    FATAL_ERROR ((0, 0, _("Error in writing to standard output")));
+  if (stdlis == stdout)
+    close_stdout ();
+
   if (exit_status == TAREXIT_FAILURE)
     error (0, 0, _("Error exit delayed from previous errors"));
   if (ferror (stderr) || fclose (stderr) != 0)
--- paxutils/gnulib.modules     7 Feb 2006 22:18:04 -0000       1.4
+++ paxutils/gnulib.modules     7 Feb 2006 23:49:31 -0000
@@ -1,6 +1,7 @@
 # List of gnulib modules needed for GNU paxutils.
 # A module name per line. Empty lines and comments are ignored.
 
+closeout
 dirname
 full-write
 getdate
--- paxutils/rmt/rmt.c  7 Feb 2006 22:18:04 -0000       1.9
+++ paxutils/rmt/rmt.c  7 Feb 2006 23:49:31 -0000
@@ -1,7 +1,7 @@
 /* Remote connection server.
 
-   Copyright (C) 1994, 1995, 1996, 1997, 1999, 2000, 2001, 2003, 2004, 2005
-   Free Software Foundation, Inc.
+   Copyright (C) 1994, 1995, 1996, 1997, 1999, 2000, 2001, 2003, 2004,
+   2005, 2006 Free Software Foundation, Inc.
 
    This program is free software; you can redistribute it and/or modify it
    under the terms of the GNU General Public License as published by the
@@ -32,6 +32,7 @@
    MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  */
 
 #include "system.h"
+#include <closeout.h>
 #include <localedir.h>
 #include <safe-read.h>
 #include <full-write.h>
@@ -260,6 +261,7 @@ Manipulate a tape drive, accepting comma
   --help     Output this help.\n"),
              program_name);
       printf (_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT);
+      close_stdout ();
     }
 
   exit (status);
@@ -563,6 +565,7 @@ main (int argc, char **argv)
     case 'v':
       version_etc (stdout, "rmt", PACKAGE_NAME, PACKAGE_VERSION,
                   "John Gilmore", "Jay Fenlason", (char *) NULL);
+      close_stdout ();
       return EXIT_SUCCESS;
 
     case -1:




reply via email to

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