gzip: fix bug with -l output to pipes
authorPaul Eggert <eggert@cs.ucla.edu>
Wed, 20 Apr 2016 00:43:09 +0000 (17:43 -0700)
committerPaul Eggert <eggert@cs.ucla.edu>
Wed, 20 Apr 2016 00:43:55 +0000 (17:43 -0700)
Problem reported by Christian Franke via Eric Blake in:
http://bugs.gnu.org/23314
* NEWS: Mention this.
* gzip.c (main): Do not close stdout twice when given -l.
Instead, -l now just fflushes stdout, so that fdatasync
can synchronize it if --synchronize is also specified.
* tests/list: New test case.
* tests/Makefile.am (TESTS): Add it.

NEWS
gzip.c
tests/Makefile.am
tests/list [new file with mode: 0755]

diff --git a/NEWS b/NEWS
index fdae647c77780cb62b12c1fcb5c70ca8cf3db8e7..8f722e504ebe7b0aba534539286d28702fb0ac73 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -4,6 +4,9 @@ GNU gzip NEWS                                    -*- outline -*-
 
 ** Bug fixes
 
+  gzip -l no longer falsely reports a write error when writing to a pipe.
+  [bug introduced in gzip-1.7]
+
   Port to Oracle Solaris Studio 12 on x86-64.
   [bug present since at least gzip-1.2.4]
 
diff --git a/gzip.c b/gzip.c
index d66530a70bdce1d19a2687658e9ef0b9f19a1e18..3b8de4d9af28fc3d559b99c1f4021e4e38e77113 100644 (file)
--- a/gzip.c
+++ b/gzip.c
@@ -664,14 +664,16 @@ int main (int argc, char **argv)
     } else {  /* Standard input */
         treat_stdin();
     }
-    if (list && !quiet && file_count > 1) {
-        do_list(-1, -1); /* print totals */
-    }
-    if (to_stdout
-        && ((synchronous
-             && (fdatasync (STDOUT_FILENO) != 0 && errno != EINVAL))
-            || close (STDOUT_FILENO) != 0)
-        && errno != EBADF)
+    if (list)
+      {
+        /* Output any totals, and check for output errors.  */
+        if (!quiet && 1 < file_count)
+          do_list (-1, -1);
+        if (fflush (stdout) != 0)
+          write_error ();
+      }
+    if (to_stdout && synchronous && fdatasync (STDOUT_FILENO) != 0
+        && errno != EINVAL && errno != EBADF)
       write_error ();
     do_exit(exit_code);
     return exit_code; /* just to avoid lint warning */
index 5022464612c4a265552f2775020507a630d1ae26..71cf4ada6bc22625c2a12e289a52f58503918774 100644 (file)
@@ -20,6 +20,7 @@ TESTS =                                       \
   help-version                         \
   hufts                                        \
   keep                                 \
+  list                                 \
   memcpy-abuse                         \
   mixed                                        \
   null-suffix-clobber                  \
diff --git a/tests/list b/tests/list
new file mode 100755 (executable)
index 0000000..7576dc3
--- /dev/null
@@ -0,0 +1,31 @@
+#!/bin/sh
+# Exercise the --list option.
+
+# Copyright 2016 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 Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+# limit so don't run it by default.
+
+. "${srcdir=.}/init.sh"; path_prepend_ ..
+
+echo zoology zucchini > in || framework_failure_
+cp in orig || framework_failure_
+
+gzip -l in && fail=1
+gzip -9 in || fail=1
+gzip -l in.gz >out1 || fail=1
+gzip -l in.gz | cat >out2 || fail=1
+compare out1 out2 || fail=1
+
+Exit $fail