gzexe: ensure file always exists
[debian/gzip] / zgrep.in
index c24be57a4318a3dea22cfb6e6840e9bca84abb5e..0660634dd4ad9c13c69de3bba8355321e4a1f505 100644 (file)
--- a/zgrep.in
+++ b/zgrep.in
@@ -3,7 +3,7 @@
 # zgrep -- a wrapper around a grep program that decompresses files as needed
 # Adapted from a version sent by Charles Levert <charles@comm.polymtl.ca>
 
-# Copyright (C) 1998, 2001-2002, 2006-2007, 2009-2016 Free Software Foundation,
+# Copyright (C) 1998, 2001-2002, 2006-2007, 2009-2017 Free Software Foundation,
 # Inc.
 
 # Copyright (C) 1993 Jean-loup Gailly
@@ -25,9 +25,9 @@
 grep='${GREP-'\''@GREP@'\''}'
 
 version='zgrep (gzip) @VERSION@
-Copyright (C) 2010-2016 Free Software Foundation, Inc.
+Copyright (C) 2010-2017 Free Software Foundation, Inc.
 This is free software.  You may redistribute copies of it under the terms of
-the GNU General Public License <http://www.gnu.org/licenses/gpl.html>.
+the GNU General Public License <https://www.gnu.org/licenses/gpl.html>.
 There is NO WARRANTY, to the extent permitted by law.
 
 Written by Jean-loup Gailly.'
@@ -55,6 +55,7 @@ files_with_matches=0
 files_without_matches=0
 no_filename=0
 with_filename=0
+pattmp=
 
 while test $# -ne 0; do
   option=$1
@@ -113,16 +114,37 @@ while test $# -ne 0; do
     # The pattern is coming from a file rather than the command-line.
     # If the file is actually stdin then we need to do a little
     # magic, since we use stdin to pass the gzip output to grep.
-    # Turn the -f option into an -e option by copying the file's
-    # contents into OPTARG.
-    case $optarg in
-    (" '-'" | " '/dev/stdin'" | " '/dev/fd/0'")
-      option=-e
-      optarg=" '"$(sed "$escape") || exit 2;;
-    esac
+    # Similarly if it is not a regular file, since it might be read repeatedly.
+    # In either of these two cases, copy the pattern into a temporary file,
+    # and use that file instead.  The pattern might contain null bytes,
+    # so we cannot simply switch to -e here.
+    if case $optarg in
+       (" '-'" | " '/dev/stdin'" | " '/dev/fd/0'")
+         :;;
+       (*)
+         eval "test ! -f$optarg";;
+       esac
+    then
+      if test -n "$pattmp"; then
+        eval "cat --$optarg" >>"$pattmp" || exit 2
+        continue
+      fi
+      trap '
+        test -n "$pattmp" && rm -f "$pattmp"
+        (exit 2); exit 2
+      ' HUP INT PIPE TERM 0
+      if type mktemp >/dev/null 2>&1; then
+        pattmp=$(mktemp) || exit 2
+      else
+        set -C
+        pattmp=${TMPDIR-/tmp}/zgrep.$$
+      fi
+      eval "cat --$optarg" >"$pattmp" || exit 2
+      optarg=' "$pattmp"'
+    fi
     have_pat=1;;
   (--h | --he | --hel | --help)
-    echo "$usage" || exit 2
+    printf '%s\n' "$usage" || exit 2
     exit;;
   (-H | --wi | --wit | --with | --with- | --with-f | --with-fi \
   | --with-fil | --with-file | --with-filen | --with-filena | --with-filenam \
@@ -136,7 +158,7 @@ while test $# -ne 0; do
   (-h | --no-f*)
     no_filename=1;;
   (-V | --v | --ve | --ver | --vers | --versi | --versio | --version)
-    echo "$version" || exit 2
+    printf '%s\n' "$version" || exit 2
     exit;;
   esac
 
@@ -232,5 +254,14 @@ do
   test 126 -le $res && break
 done
 
+if test -n "$pattmp"; then
+  rm -f "$pattmp" || {
+    r=$?
+    test $r -lt 2 && r=2
+    test $res -lt $r && res=$r
+  }
+  trap - HUP INT PIPE TERM 0
+fi
+
 test 128 -le $res && kill -$(expr $res % 128) $$
 exit $res