On 2021-01-08 Lasse Collin wrote: > It's tempting to ignore exit statuses >= 128 at the end of the script > where it current checks for "$xz_status" -eq 0 but that doesn't work > because in the middle of the script there is also this: > > case $xz_status in > *[1-9]*) xz_status=1;; > *) xz_status=0;; > esac > > There xz_status contains two numbers and the "case" finds out if they > are both zero. Perhaps this "case" should be replaced with something > more sophisticated that checks both numbers separately and ignores > values >= 128.
I found it easy to change the above "case" and ignore >= 128 at the bottom of the script. But that still isn't enough. gzip -q turns SIGPIPE into exit status of 2. Ignoring 2 would work for gzip but that is incompatible with bzip2 which uses exit status 2 to indicate corrupt input. Trying to handle exit statuses separately for each compressor is complicated because two different tools may be in use at the same time. Getting rid of gzip -q sounds more reasonable. The script uses -cdfq to decompress and I'm not sure why the -q is there. There is an exception when only one argument is given, then -cd is used. The -f option is needed with xz (and it's fine with gzip too) to handle uncompressed files: xz -cdf or gzip -cdf with unknown file format behaves like cat and just copies the input to the output. The use of -f (and the non-use in the single-file case) looks fine, but I don't know what to think about -q. Perhaps it hides warnings in some rare cases where they aren't wanted. The following patch replace -cdfq with -cdf and ignores decompressor exit statuses >= 128. Could someone test if it fixes the original bug without introducing any obvious new bugs with some of the supported compression tools? diff --git a/src/scripts/xzdiff.in b/src/scripts/xzdiff.in index eb7825c..b285572 100644 --- a/src/scripts/xzdiff.in +++ b/src/scripts/xzdiff.in @@ -116,23 +116,17 @@ elif test $# -eq 2; then if test "$1$2" = --; then xz_status=$( exec 4>&1 - ($xz1 -cdfq - 4>&-; echo $? >&4) 3>&- | + ($xz1 -cdf - 4>&-; echo $? >&4) 3>&- | eval "$cmp" - - >&3 ) elif # Reject Solaris 8's buggy /bin/bash 2.03. echo X | (echo X | eval "$cmp" /dev/fd/5 - >/dev/null 2>&1) 5<&0; then xz_status=$( exec 4>&1 - ($xz1 -cdfq -- "$1" 4>&-; echo $? >&4) 3>&- | - ( ($xz2 -cdfq -- "$2" 4>&-; echo $? >&4) 3>&- 5<&- </dev/null | + ($xz1 -cdf -- "$1" 4>&-; echo $? >&4) 3>&- | + ( ($xz2 -cdf -- "$2" 4>&-; echo $? >&4) 3>&- 5<&- </dev/null | eval "$cmp" /dev/fd/5 - >&3) 5<&0 ) - cmp_status=$? - case $xz_status in - *[1-9]*) xz_status=1;; - *) xz_status=0;; - esac - (exit $cmp_status) else F=`expr "/$2" : '.*/\(.*\)[-.][ablmotxz2]*$'` || F=$prog tmp= @@ -161,10 +155,10 @@ elif test $# -eq 2; then mkdir -- "${TMPDIR-/tmp}/$prog.$$" || exit 2 tmp="${TMPDIR-/tmp}/$prog.$$" fi - $xz2 -cdfq -- "$2" > "$tmp/$F" || exit 2 + $xz2 -cdf -- "$2" > "$tmp/$F" || exit 2 xz_status=$( exec 4>&1 - ($xz1 -cdfq -- "$1" 4>&-; echo $? >&4) 3>&- | + ($xz1 -cdf -- "$1" 4>&-; echo $? >&4) 3>&- | eval "$cmp" - '"$tmp/$F"' >&3 ) cmp_status=$? @@ -175,7 +169,7 @@ elif test $# -eq 2; then *) xz_status=$( exec 4>&1 - ($xz1 -cdfq -- "$1" 4>&-; echo $? >&4) 3>&- | + ($xz1 -cdf -- "$1" 4>&-; echo $? >&4) 3>&- | eval "$cmp" - '"$2"' >&3 );; esac;; @@ -184,7 +178,7 @@ elif test $# -eq 2; then *[-.][zZ] | *_z | *[-.][gx]z | *[-.]bz2 | *[-.]lzma | *.t[abglx]z | *.tbz2 | *[-.]lzo | *.tzo | -) xz_status=$( exec 4>&1 - ($xz2 -cdfq -- "$2" 4>&-; echo $? >&4) 3>&- | + ($xz2 -cdf -- "$2" 4>&-; echo $? >&4) 3>&- | eval "$cmp" '"$1"' - >&3 );; *) @@ -197,5 +191,9 @@ else fi cmp_status=$? -test "$xz_status" -eq 0 || exit 2 +for num in $xz_status ; do + test "$num" -eq 0 && continue + test "$num" -ge 128 && continue + exit 2 +done exit $cmp_status -- Lasse Collin | IRC: Larhzu @ IRCnet & Freenode