Repository: facebook/zstd

Problem statement:
zstdgrep returns 0 on non-match
The return code of grep is often used—particularly with "grep -q", but not always—in a script to detect the presence or absence of a match.  And zgrep preserves this behavior.  But zstdgrep does not:
```
$ echo a | gzip | zgrep a; echo $?
a
0
$ echo a | gzip | zgrep b; echo $?
1
$ echo a | zstd | zstdgrep a; echo $?
a
0
$ echo a | zstd | zstdgrep b; echo $?
0
```
Even with "zstdgrep -q", a non-match still returns 0.
I'd recommend bringing zstdgrep in line.


Hints:
Fixed by @lzutao 
With zstd 1.3.8, zstdgrep seem to return 1, both on match and non-match when used on files.

```
zgrep "hello" hello.zstd; echo $?
hello
1
```
Please see this [bug report:](https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=918390) for details and a proposed patch.

Noticed.
The `test-zstdgrep` script must be improved, we should have caught this one.
It currently only uses piped data.
File access must be added to be continuously tested.

Patch:
diff --git a/programs/zstdgrep b/programs/zstdgrep
index a10e0710a29..cb804b8bead 100755
--- a/programs/zstdgrep
+++ b/programs/zstdgrep
@@ -22,8 +22,8 @@
 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-grep=grep
-zcat=zstdcat
+grep=${GREP:-grep}
+zcat=${ZCAT:-zstdcat}
 
 endofopts=0
 pattern_found=0
@@ -31,12 +31,13 @@ grep_args=""
 hyphen=0
 silent=0
 
-prg=$(basename "$0")
+prog=${0##*/}
 
 # handle being called 'zegrep' or 'zfgrep'
-case "${prg}" in
-    *zegrep) grep_args="-E";;
-    *zfgrep) grep_args="-F";;
+case $prog in
+    *egrep*) prog=zegrep; grep_args='-E';;
+    *fgrep*) prog=zfgrep; grep_args='-F';;
+    *)       prog=zstdgrep;;
 esac
 
 # skip all options and pass them on to grep taking care of options
@@ -47,7 +48,7 @@ while [ "$#" -gt 0 ] && [ "${endofopts}" -eq 0 ]; do
     # from GNU grep-2.5.1 -- keep in sync!
         -[ABCDXdefm])
             if [ "$#" -lt 2 ]; then
-                printf '%s: missing argument for %s flag\n' "${prg}" "$1" >&2
+                printf '%s: missing argument for %s flag\n' "${prog}" "$1" >&2
                 exit 1
             fi
             case "$1" in
@@ -94,7 +95,7 @@ if [ "${pattern_found}" -lt 1 ]; then
     elif [ "${hyphen}" -gt 0 ]; then
         pattern="-"
     else
-        printf '%s: missing pattern\n' "${prg}" >&2
+        printf '%s: missing pattern\n' "${prog}" >&2
         exit 1
     fi
 fi
@@ -113,16 +114,11 @@ else
     if [ "${silent}" -lt 1 ] && [ "$#" -gt 1 ]; then
         grep_args="-H ${grep_args}"
     fi
-    CUR_EXIT_CODE=0
-    EXIT_CODE=1
     set -f
     while [ "$#" -gt 0 ]; do
         # shellcheck disable=SC2086
         "${zcat}" -fq -- "$1" | "${grep}" --label="${1}" ${grep_args} -- "${pattern}" -
-        CUR_EXIT_CODE=$?
-        if [ "${CUR_EXIT_CODE}" -eq 0 ] && [ "${EXIT_CODE}" -ne 1 ]; then
-            EXIT_CODE=0
-        fi
+        [ "$?" -ne 0 ] && EXIT_CODE=1
         shift
     done
     set +f


Test patch:
diff --git a/tests/Makefile b/tests/Makefile
index 25bd5c84ef9..2daf0970f07 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -353,8 +353,12 @@ test-gzstd: gzstd
 	$(RM) *.gz *.zst README2.md gz_zstd zstd_gz hello.txt
 
 test-zstdgrep: gzstd
-	@echo a | $(PRGDIR)/zstd | $(PRGDIR)/zstdgrep a
-	@echo a | $(PRGDIR)/zstd | $(PRGDIR)/zstdgrep b && return 1 || return 0
+	-[ -f /tmp/zstdcat ] || ln -s $(PWD)/$(PRGDIR)/zstd /tmp/zstdcat
+	echo a | $(PRGDIR)/zstd | env ZCAT=/tmp/zstdcat $(PRGDIR)/zstdgrep a
+	echo a | $(PRGDIR)/zstd | env ZCAT=/tmp/zstdcat $(PRGDIR)/zstdgrep b && return 1 || return 0
+	-echo 'hello world' > test.txt && $(PRGDIR)/zstd test.txt
+	env ZCAT=/tmp/zstdcat $(PRGDIR)/zstdgrep hello test.txt.zst
+	env ZCAT=/tmp/zstdcat $(PRGDIR)/zstdgrep weird test.txt.zst && return 1 || return 0
 
 test-fullbench: fullbench datagen
 	$(QEMU_SYS) ./fullbench -i1