From c610a01d7dbe0e6586f94bfb5f8b540a2f28b1c5 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Mon, 11 Mar 2024 11:38:55 -0700 Subject: [PATCH 1/3] fix #3719 only disable `--rm` at end of command line parsing, so that `-c` only disables `--rm` if it's effectively selected, and not if it's overriden by a later `-o FILE` command. --- programs/zstd.1.md | 8 +++++--- programs/zstdcli.c | 16 ++++++++++++---- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/programs/zstd.1.md b/programs/zstd.1.md index c5d0ef70a..b11ad900d 100644 --- a/programs/zstd.1.md +++ b/programs/zstd.1.md @@ -225,15 +225,17 @@ the last one takes effect. This parameter defines a loose target: compressed blocks will target this size "on average", but individual blocks can still be larger or smaller. Enabling this feature can decrease compression speed by up to ~10% at level 1. Higher levels will see smaller relative speed regression, becoming invisible at higher settings. -* `-o FILE`: - save result into `FILE`. * `-f`, `--force`: disable input and output checks. Allows overwriting existing files, input from console, output to stdout, operating on links, block devices, etc. During decompression and when the output destination is stdout, pass-through unrecognized formats as-is. * `-c`, `--stdout`: - write to standard output (even if it is the console); keep original files unchanged. + write to standard output (even if it is the console); keep original files (disable `--rm`). +* `-o FILE`: + save result into `FILE`. + This command is in conflict with `-c`. + If both are present on the command line, the last expressed one wins. * `--[no-]sparse`: enable / disable sparse FS support, to make files with many zeroes smaller on disk. diff --git a/programs/zstdcli.c b/programs/zstdcli.c index 1cb16ef50..4ea9034a1 100644 --- a/programs/zstdcli.c +++ b/programs/zstdcli.c @@ -1176,7 +1176,10 @@ int main(int argCount, const char* argv[]) operation=zom_decompress; argument++; break; /* Force stdout, even if stdout==console */ - case 'c': forceStdout=1; outFileName=stdoutmark; removeSrcFile=0; argument++; break; + case 'c': forceStdout=1; outFileName=stdoutmark; argument++; break; + + /* destination file name */ + case 'o': argument++; NEXT_FIELD(outFileName); break; /* do not store filename - gzip compatibility - nothing to do */ case 'n': argument++; break; @@ -1202,9 +1205,6 @@ int main(int argCount, const char* argv[]) /* test compressed file */ case 't': operation=zom_test; argument++; break; - /* destination file name */ - case 'o': argument++; NEXT_FIELD(outFileName); break; - /* limit memory */ case 'M': argument++; @@ -1367,6 +1367,14 @@ int main(int argCount, const char* argv[]) #endif } + /* disable --rm when writing to stdout */ + if (!strcmp(outFileName, stdoutmark)) { + if (removeSrcFile) { + DISPLAYLEVEL(2, "warning: source not removed when writing to stdout \n"); + removeSrcFile = 0; + } + } + /* Check if benchmark is selected */ if (operation==zom_bench) { #ifndef ZSTD_NOBENCH From fbd9e628ae124d4bbf4db0b8afd54b6b6e653b29 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Mon, 11 Mar 2024 12:17:34 -0700 Subject: [PATCH 2/3] added tests --- programs/zstdcli.c | 10 +--------- tests/playTests.sh | 32 ++++++++++++++++++++++++++++++-- 2 files changed, 31 insertions(+), 11 deletions(-) diff --git a/programs/zstdcli.c b/programs/zstdcli.c index 4ea9034a1..9dd6b051a 100644 --- a/programs/zstdcli.c +++ b/programs/zstdcli.c @@ -962,7 +962,7 @@ int main(int argCount, const char* argv[]) if (!strcmp(argument, "--help")) { usageAdvanced(programName); CLEAN_RETURN(0); } if (!strcmp(argument, "--verbose")) { g_displayLevel++; continue; } if (!strcmp(argument, "--quiet")) { g_displayLevel--; continue; } - if (!strcmp(argument, "--stdout")) { forceStdout=1; outFileName=stdoutmark; removeSrcFile=0; continue; } + if (!strcmp(argument, "--stdout")) { forceStdout=1; outFileName=stdoutmark; continue; } if (!strcmp(argument, "--ultra")) { ultra=1; continue; } if (!strcmp(argument, "--check")) { FIO_setChecksumFlag(prefs, 2); continue; } if (!strcmp(argument, "--no-check")) { FIO_setChecksumFlag(prefs, 0); continue; } @@ -1367,14 +1367,6 @@ int main(int argCount, const char* argv[]) #endif } - /* disable --rm when writing to stdout */ - if (!strcmp(outFileName, stdoutmark)) { - if (removeSrcFile) { - DISPLAYLEVEL(2, "warning: source not removed when writing to stdout \n"); - removeSrcFile = 0; - } - } - /* Check if benchmark is selected */ if (operation==zom_bench) { #ifndef ZSTD_NOBENCH diff --git a/tests/playTests.sh b/tests/playTests.sh index bf5fba89b..dc7794654 100755 --- a/tests/playTests.sh +++ b/tests/playTests.sh @@ -234,12 +234,23 @@ unset ZSTD_CLEVEL println "test : compress to stdout" zstd tmp -c > tmpCompressed zstd tmp --stdout > tmpCompressed # long command format -println "test : compress to named file" + +println "test : compress to named file (-o)" rm -f tmpCompressed zstd tmp -o tmpCompressed test -f tmpCompressed # file must be created + println "test : force write, correct order" zstd tmp -fo tmpCompressed + +println "test : -c + -o : last one wins" +rm -f tmpOut +zstd tmp -c > tmpCompressed -o tmpOut +test -f tmpOut # file must be created +rm -f tmpCompressed +zstd tmp -o tmpOut -c > tmpCompressed +test -f tmpCompressed # file must be created + println "test : forgotten argument" cp tmp tmp2 zstd tmp2 -fo && die "-o must be followed by filename " @@ -394,6 +405,8 @@ println "test: --rm is disabled when output is stdout" test -f tmp zstd --rm tmp -c > $INTOVOID test -f tmp # tmp shall still be there +zstd --rm tmp --stdout > $INTOVOID +test -f tmp # tmp shall still be there zstd -f --rm tmp -c > $INTOVOID test -f tmp # tmp shall still be there zstd -f tmp -c > $INTOVOID --rm @@ -411,7 +424,22 @@ zstd -f tmp tmp2 -o tmp3.zst --rm # just warns, no prompt test -f tmp test -f tmp2 zstd -q tmp tmp2 -o tmp3.zst --rm && die "should refuse to concatenate" - +println "test: --rm is active with -o when single input" +rm -f tmp2.zst +zstd --rm tmp2 -o tmp2.zst +test -f tmp2.zst +test ! -f tmp2 +println "test: -c followed by -o => -o wins, so --rm remains active" # (#3719) +rm tmp2.zst +cp tmp tmp2 +zstd --rm tmp2 -c > $INTOVOID -o tmp2.zst +test ! -f tmp2 +println "test: -o followed by -c => -c wins, so --rm is disabled" # (#3719) +rm tmp3.zst +cp tmp tmp2 +zstd -v --rm tmp2 -o tmp2.zst -c > tmp3.zst +test -f tmp2 +test -f tmp3.zst println "test : should quietly not remove non-regular file" println hello > tmp zstd tmp -f -o "$DEVDEVICE" 2>tmplog > "$INTOVOID" From 1362699e875994689390bbee3cba87d2c11a11fb Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Mon, 11 Mar 2024 12:23:37 -0700 Subject: [PATCH 3/3] minor man page clarification --- programs/zstd.1.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/programs/zstd.1.md b/programs/zstd.1.md index b11ad900d..646e3cf28 100644 --- a/programs/zstd.1.md +++ b/programs/zstd.1.md @@ -234,8 +234,8 @@ the last one takes effect. write to standard output (even if it is the console); keep original files (disable `--rm`). * `-o FILE`: save result into `FILE`. - This command is in conflict with `-c`. - If both are present on the command line, the last expressed one wins. + Note that this operation is in conflict with `-c`. + If both operations are present on the command line, the last expressed one wins. * `--[no-]sparse`: enable / disable sparse FS support, to make files with many zeroes smaller on disk.