bug-gnu-utils
[Top][All Lists]
Advanced

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

tar ignores complaints from gzip


From: Simon Gerraty
Subject: tar ignores complaints from gzip
Date: Thu, 27 Sep 2001 11:39:26 -0700 (PDT)

>Submitter-Id:   current-users
>Originator:     Simon Gerraty
>Organization:   Juniper Networks Inc.
>Confidential:   no 
>Synopsis:       tar ignores complaints from gzip
>Severity:       serious
>Priority:       medium
>Category:       gnu
>Release:        FreeBSD 4.2-RELEASE i386
>Class:          sw-bug 
>Environment: 

        

>Description: 

        
The patch below fixes a couple of issues with how tar interacts with
its child - gzip.

1. When the child (gzip) exists with a bad status, tar reports it but does
   not propagate the failure to its caller.  This has lead to pkg_add
   attempting to install corrupted binaries when a gzip fails CRC checks
   but tar has read the end of archive marker before gzip exits.

   Tar should never ignore a bad exit status from its child.


2. Tar closes the pipe as soon as it reads the end of archive.
   It understands that this might result in its child dying due to SIGPIPE
   and it ignores that condition.
   However, if the child catches SIGPIPE and just exit's 1, the fix above
   will result in an unnecessary failure.

   Tar should read EOF from the child before closing the pipe.

--sjg

>How-To-Repeat: 

        

>Fix: 

        

I can't get a connection to anoncvs.freebsd.org, but the following patch
applies cleanly to -current.

Index: buffer.c
===================================================================
retrieving revision 1.1.1.1
diff -u -p -r1.1.1.1 buffer.c
--- buffer.c    1997/02/26 02:34:43     1.1.1.1
+++ buffer.c    2001/09/19 16:17:31
@@ -1254,6 +1254,20 @@ close_archive ()
   if (f_verify)
     verify_volume ();
 
+#ifndef __MSDOS__
+  /*
+   * closing the child's pipe before reading EOF guarantees that it
+   * will be unhappy - SIGPIPE, or exit 1.
+   * Either way it can screw us, so play nice.
+   */
+  if (childpid && ar_reading) {
+      char buf[BUFSIZ];
+      
+      while ((c = read(archive, buf, sizeof(buf))) > 0)
+         continue;
+  }
+#endif
+      
   if ((c = rmtclose (archive)) < 0)
     msg_perror ("Warning: can't close %s(%d,%d)", ar_files[cur_ar_file], 
archive, c);
 
@@ -1291,9 +1305,11 @@ close_archive ()
                   */
                  /* Do nothing. */
                }
-             else if (WEXITSTATUS (status))
+             else if (WEXITSTATUS (status)) {
                msg ("child returned status %d",
                     WEXITSTATUS (status));
+                 exit (EX_BADARCH);
+             }
            }
        }
     }



reply via email to

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