Subject: bin/27213: pax doesn't honour SIGPIPE when listing
To: None <gnats-bugs@gnats.netbsd.org>
From: Greg A. Woods <woods@weird.com>
List: netbsd-bugs
Date: 10/10/2004 16:21:53
>Number: 27213
>Category: bin
>Synopsis: pax doesn't honour SIGPIPE when listing
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: bin-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Sun Oct 10 20:23:00 UTC 2004
>Closed-Date:
>Last-Modified:
>Originator: Greg A. Woods
>Release: NetBSD-current
>Organization:
Planix, Inc.; Toronto, Ontario; Canada
>Environment:
all
>Description:
The internal code in pax assumes that write errors will be
detected and thus SIGPIPE can be ignored.
However this is not true for the listing modes (-t and -v).
When "pax -v" output is piped to "head" or "less", etc. and the
viewing is stopped well before pax is done then the command
"hangs" until the whole archive is read instead of immediatly
quitting as follows:
$ gzcat .../binary/sets/base.tgz | pax -v | head
drwxr-xr-x 2 root wheel 0 Jun 22 14:58 .
drwxr-xr-x 2 root wheel 0 Jun 21 21:55 ./altroot
drwxr-xr-x 2 root wheel 0 Jun 22 14:52 ./bin
-r-xr-xr-x 1 root wheel 218504 Jun 21 17:36 ./bin/awk
-r-xr-xr-x 1 root wheel 76649 Jun 21 17:36 ./bin/cat
-r-xr-xr-x 1 root wheel 79587 Jun 21 17:36 ./bin/chio
-r-xr-xr-x 1 root wheel 90868 Jun 21 17:36 ./bin/chmod
-r-xr-xr-x 1 root wheel 94698 Jun 21 17:36 ./bin/cp
-r-xr-xr-x 1 root wheel 99661 Jun 21 17:36 ./bin/date
-r-xr-xr-x 1 root wheel 109261 Jun 21 17:36 ./bin/dd
pax: Listing incomplete. (Broken pipe)
>How-To-Repeat:
get really annoyed one last time that pax still doesn't honour
SIGPIPE when listing large archives
>Fix:
Index: ar_subs.c
===================================================================
RCS file: /cvs/master/m-NetBSD/main/src/bin/pax/ar_subs.c,v
retrieving revision 1.31
diff -u -r1.31 ar_subs.c
--- ar_subs.c 22 Aug 2004 16:46:18 -0000 1.31
+++ ar_subs.c 10 Oct 2004 20:13:22 -0000
@@ -143,6 +143,16 @@
break;
if (res == 0)
ls_list(arcn, now, stdout);
+ /*
+ * if there's an error writing to stdout then we must
+ * stop now -- we're probably writing to a pipe that
+ * has been closed by the reader.
+ */
+ if (ferror(stdout)) {
+ syswarn((errno == EPIPE) ? 0 : 1,
+ errno, "Listing incomplete.");
+ break;
+ }
}
/*
* skip to next archive format header using values calculated
>Release-Note:
>Audit-Trail:
>Unformatted: