cli: display a warning whenever default output is stdout while input != stdin
authorYann Collet <cyan@fb.com>
Sat, 20 Apr 2019 00:08:40 +0000 (17:08 -0700)
committerYann Collet <cyan@fb.com>
Sat, 20 Apr 2019 00:08:40 +0000 (17:08 -0700)
This behavior has been preserved for compatibility with existing ecosystem.
But it's problematic, as some environment start `lz4` without identifying stdout as console by default,
leading to a change of behavior for a same line of script.

A more sensible policy would be to default to stdout only when input is stdin.

Soft change for the time being : keep the behavior, just print a warning message.
User should prefer `-c` to explicitly select `stdout`.

Also : updated tests in Makefile to explicitly select `stdout` with `-c`.

programs/lz4cli.c
tests/Makefile

index 8bd7042..279aaf1 100644 (file)
@@ -652,7 +652,15 @@ int main(int argc, const char** argv)
 
     /* No output filename ==> try to select one automatically (when possible) */
     while ((!output_filename) && (multiple_inputs==0)) {
-        if (!IS_CONSOLE(stdout)) { output_filename=stdoutmark; break; }   /* Default to stdout whenever possible (i.e. not a console) */
+
+        if (!IS_CONSOLE(stdout)) {
+            /* Default to stdout whenever stdout is not the console.
+             * Note : this policy is likely to change in the future, don't rely on it !
+             * prefer using an explicit `-c` flag */
+            DISPLAYLEVEL(1, "Warning : using stdout as default output. Do not rely on this behavior: use explicit `-c` instead ! \n");
+            output_filename=stdoutmark;
+            break;
+        }
         if (mode == om_auto) {  /* auto-determine compression or decompression, based on file extension */
             mode = determineOpMode(input_filename);
         }
@@ -682,10 +690,14 @@ int main(int argc, const char** argv)
         break;
     }
 
-    /* Check if output is defined as console; trigger an error in this case */
+    if (multiple_inputs==0) assert(output_filename);
+    /* when multiple_inputs==1, output_filename may simply be useless,
+     * however, output_filename must be !NULL for next strcmp() tests */
     if (!output_filename) output_filename = "*\\dummy^!//";
+
+    /* Check if output is defined as console; trigger an error in this case */
     if (!strcmp(output_filename,stdoutmark) && IS_CONSOLE(stdout) && !forceStdout) {
-        DISPLAYLEVEL(1, "refusing to write to console without -c\n");
+        DISPLAYLEVEL(1, "refusing to write to console without -c \n");
         exit(1);
     }
     /* Downgrade notification level in stdout and multiple file mode */
@@ -701,21 +713,23 @@ int main(int argc, const char** argv)
     LZ4IO_setNotificationLevel((int)displayLevel);
     if (ifnIdx == 0) multiple_inputs = 0;
     if (mode == om_decompress) {
-        if (multiple_inputs)
-            operationResult = LZ4IO_decompressMultipleFilenames(prefs, inFileNames, ifnIdx, !strcmp(output_filename,stdoutmark) ? stdoutmark : LZ4_EXTENSION);
-        else
+        if (multiple_inputs) {
+            assert(ifnIdx <= INT_MAX);
+            operationResult = LZ4IO_decompressMultipleFilenames(prefs, inFileNames, (int)ifnIdx, !strcmp(output_filename,stdoutmark) ? stdoutmark : LZ4_EXTENSION);
+        } else {
             operationResult = DEFAULT_DECOMPRESSOR(prefs, input_filename, output_filename);
+        }
     } else {   /* compression is default action */
         if (legacy_format) {
             DISPLAYLEVEL(3, "! Generating LZ4 Legacy format (deprecated) ! \n");
             LZ4IO_compressFilename_Legacy(prefs, input_filename, output_filename, cLevel);
         } else {
-            if (multiple_inputs)
-                operationResult = LZ4IO_compressMultipleFilenames(prefs, inFileNames, ifnIdx, !strcmp(output_filename,stdoutmark) ? stdoutmark : LZ4_EXTENSION, cLevel);
-            else
+            if (multiple_inputs) {
+                assert(ifnIdx <= INT_MAX);
+                operationResult = LZ4IO_compressMultipleFilenames(prefs, inFileNames, (int)ifnIdx, !strcmp(output_filename,stdoutmark) ? stdoutmark : LZ4_EXTENSION, cLevel);
+            } else {
                 operationResult = DEFAULT_COMPRESSOR(prefs, input_filename, output_filename, cLevel);
-        }
-    }
+    }   }   }
 
 _cleanup:
     if (main_pause) waitEnter();
index 70cae63..579999c 100644 (file)
@@ -176,15 +176,15 @@ test-install: lz4 lib liblz4.pc
 test-lz4-sparse: lz4 datagen
        @echo "\n ---- test sparse file support ----"
        ./datagen -g5M  -P100 > tmplsdg5M
-       $(LZ4) -B4D tmplsdg5M | $(LZ4) -dv --sparse > tmplscB4
+       $(LZ4) -B4D tmplsdg5M -c | $(LZ4) -dv --sparse > tmplscB4
        $(DIFF) -s tmplsdg5M tmplscB4
-       $(LZ4) -B5D tmplsdg5M | $(LZ4) -dv --sparse > tmplscB5
+       $(LZ4) -B5D tmplsdg5M -c | $(LZ4) -dv --sparse > tmplscB5
        $(DIFF) -s tmplsdg5M tmplscB5
-       $(LZ4) -B6D tmplsdg5M | $(LZ4) -dv --sparse > tmplscB6
+       $(LZ4) -B6D tmplsdg5M -c | $(LZ4) -dv --sparse > tmplscB6
        $(DIFF) -s tmplsdg5M tmplscB6
-       $(LZ4) -B7D tmplsdg5M | $(LZ4) -dv --sparse > tmplscB7
+       $(LZ4) -B7D tmplsdg5M -c | $(LZ4) -dv --sparse > tmplscB7
        $(DIFF) -s tmplsdg5M tmplscB7
-       $(LZ4) tmplsdg5M | $(LZ4) -dv --no-sparse > tmplsnosparse
+       $(LZ4) tmplsdg5M -c | $(LZ4) -dv --no-sparse > tmplsnosparse
        $(DIFF) -s tmplsdg5M tmplsnosparse
        ls -ls tmpls*
        ./datagen -s1 -g1200007 -P100 | $(LZ4) | $(LZ4) -dv --sparse > tmplsodd   # Odd size file (to generate non-full last block)
@@ -200,7 +200,7 @@ test-lz4-sparse: lz4 datagen
        cat tmplsdg1M tmplsdg1M > tmpls2M
        $(LZ4) -B5 -v tmplsdg1M tmplsc
        $(LZ4) -d -v tmplsc tmplsr
-       $(LZ4) -d -v tmplsc >> tmplsr
+       $(LZ4) -d -v tmplsc -c >> tmplsr
        ls -ls tmp*
        $(DIFF) tmpls2M tmplsr
        @$(RM) tmpls*
@@ -208,8 +208,8 @@ test-lz4-sparse: lz4 datagen
 test-lz4-contentSize: lz4 datagen
        @echo "\n ---- test original size support ----"
        ./datagen -g15M > tmplc1
-       $(LZ4) -v tmplc1 | $(LZ4) -t
-       $(LZ4) -v --content-size tmplc1 | $(LZ4) -d > tmplc2
+       $(LZ4) -v tmplc1 -c | $(LZ4) -t
+       $(LZ4) -v --content-size tmplc1 -c | $(LZ4) -d > tmplc2
        $(DIFF) -s tmplc1 tmplc2
        @$(RM) tmplc*
 
@@ -218,10 +218,10 @@ test-lz4-frame-concatenation: lz4 datagen
        @echo -n > tmp-lfc-empty
        @echo hi > tmp-lfc-nonempty
        cat tmp-lfc-nonempty tmp-lfc-empty tmp-lfc-nonempty > tmp-lfc-src
-       @$(LZ4) -zq tmp-lfc-empty > tmp-lfc-empty.lz4
-       @$(LZ4) -zq tmp-lfc-nonempty > tmp-lfc-nonempty.lz4
+       $(LZ4) -zq tmp-lfc-empty -c > tmp-lfc-empty.lz4
+       $(LZ4) -zq tmp-lfc-nonempty -c > tmp-lfc-nonempty.lz4
        cat tmp-lfc-nonempty.lz4 tmp-lfc-empty.lz4 tmp-lfc-nonempty.lz4 > tmp-lfc-concat.lz4
-       $(LZ4) -d tmp-lfc-concat.lz4 > tmp-lfc-result
+       $(LZ4) -d tmp-lfc-concat.lz4 -c > tmp-lfc-result
        cmp tmp-lfc-src tmp-lfc-result
        @$(RM) tmp-lfc-*
        @echo frame concatenation test completed
@@ -341,8 +341,8 @@ test-lz4-dict: lz4 datagen
        for l in 0 1 4 128 32767 32768 32769 65535 65536 65537 98303 98304 98305 131071 131072 131073; do \
                ./datagen -g$$l > tmp-dict-$$l; \
                $(DD) if=tmp-dict-$$l of=tmp-dict-$$l-tail bs=1 count=65536 skip=$$((l > 65536 ? l - 65536 : 0)); \
-               < tmp-dict-$$l      $(LZ4) -D stdin tmp-dict-data-128KB | $(LZ4) -dD tmp-dict-$$l-tail | $(DIFF) - tmp-dict-data-128KB; \
-               < tmp-dict-$$l-tail $(LZ4) -D stdin tmp-dict-data-128KB | $(LZ4) -dD tmp-dict-$$l      | $(DIFF) - tmp-dict-data-128KB; \
+               < tmp-dict-$$l      $(LZ4) -D stdin tmp-dict-data-128KB -c | $(LZ4) -dD tmp-dict-$$l-tail | $(DIFF) - tmp-dict-data-128KB; \
+               < tmp-dict-$$l-tail $(LZ4) -D stdin tmp-dict-data-128KB -c | $(LZ4) -dD tmp-dict-$$l      | $(DIFF) - tmp-dict-data-128KB; \
        done
 
        @$(RM) tmp-dict*