fix #285 : lz4cat doesn't work with stdin (reported by @beiDei8z)
authorYann Collet <cyan@fb.com>
Thu, 8 Dec 2016 22:17:40 +0000 (14:17 -0800)
committerYann Collet <cyan@fb.com>
Thu, 8 Dec 2016 22:25:04 +0000 (14:25 -0800)
programs/lz4.1.md
programs/lz4cli.c
tests/Makefile

index 83a08b6..48f3152 100644 (file)
@@ -34,6 +34,7 @@ Differences are :
   * `lz4` preserves original files
   * `lz4` compresses a single file by default (see `-m` for multiple files)
   * `lz4 file1 file2` means : compress file1 _into_ file2
+  * `lz4 file.lz4` will default to decompression (use `-z` to force compression)
   * `lz4` shows real-time notification statistics
      during compression or decompression of a single file
      (use `-q` to silent them)
@@ -43,15 +44,16 @@ Differences are :
     `file` is compressed into `file.lz4`.
   * As a consequence of previous rules, note the following example :
     `lz4 file | consumer` sends compressed data to `consumer` through `stdout`,
-    hence it does _not_ create any `file.lz4`.
+    hence it does _not_ create `file.lz4`.
 
 Default behaviors can be modified by opt-in commands, detailed below.
 
   * `lz4 -m` makes it possible to provide multiple input filenames,
     which will be compressed into files using suffix `.lz4`.
-    Progress notifications are also disabled by default.
+    Progress notifications are also disabled by default (use `-v` to enable them).
     This mode has a behavior which more closely mimics `gzip` command line,
-    with the main difference being that source files are preserved by default.
+    with the main remaining difference being that source files are preserved by default.
+  * Similarly, `lz4 -m -d` can decompress multiple `*.lz4` files.
   * It's possible to opt-in to erase source files
     on successful compression or decompression, using `--rm` command.
   * Consequently, `lz4 -m --rm` behaves the same as `gzip`.
index b63d69d..5bd06d9 100644 (file)
@@ -313,6 +313,7 @@ int main(int argc, const char** argv)
         DISPLAY("Allocation error : not enough memory \n");
         return 1;
     }
+    inFileNames[0] = stdinmark;
     LZ4IO_setOverwrite(0);
 
     /* lz4cat predefined behavior */
@@ -468,7 +469,7 @@ int main(int argc, const char** argv)
                     break;
 
 #ifdef UTIL_HAS_CREATEFILELIST
-                        /* recursive */
+                    /* recursive */
                 case 'r': recursive=1;  /* without break */
 #endif
                     /* Treat non-option args as input files.  See https://code.google.com/p/lz4/issues/detail?id=151 */
@@ -482,7 +483,7 @@ int main(int argc, const char** argv)
                         iters = readU32FromChar(&argument);
                         argument--;
                         BMK_setNotificationLevel(displayLevel);
-                        BMK_SetNbSeconds(iters);
+                        BMK_SetNbSeconds(iters);   /* notification if displayLevel >= 3 */
                     }
                     break;
 
@@ -555,6 +556,9 @@ int main(int argc, const char** argv)
         DISPLAYLEVEL(1, "refusing to read from a console\n");
         exit(1);
     }
+    /* if input==stdin and no output defined, stdout becomes default output */
+    if (!strcmp(input_filename, stdinmark) && !output_filename)
+        output_filename = stdoutmark;
 
     /* No output filename ==> try to select one automatically (when possible) */
     while ((!output_filename) && (multiple_inputs==0)) {
@@ -592,20 +596,19 @@ int main(int argc, const char** argv)
         break;
     }
 
-    if (!output_filename) output_filename = "*\\dummy^!//";
-
     /* Check if output is defined as console; trigger an error in this case */
+    if (!output_filename) output_filename = "*\\dummy^!//";
     if (!strcmp(output_filename,stdoutmark) && IS_CONSOLE(stdout) && !forceStdout) {
         DISPLAYLEVEL(1, "refusing to write to console without -c\n");
         exit(1);
     }
-
     /* Downgrade notification level in stdout and multiple file mode */
     if (!strcmp(output_filename,stdoutmark) && (displayLevel==2)) displayLevel=1;
     if ((multiple_inputs) && (displayLevel==2)) displayLevel=1;
 
     /* IO Stream/File */
     LZ4IO_setNotificationLevel(displayLevel);
+    if (ifnIdx == 0) multiple_inputs = 0;
     if (mode == om_decompress) {
         if (multiple_inputs)
             operationResult = LZ4IO_decompressMultipleFilenames(inFileNames, ifnIdx, !strcmp(output_filename,stdoutmark) ? stdoutmark : LZ4_EXTENSION);
index eb36abf..01b45bc 100644 (file)
@@ -239,6 +239,11 @@ test-lz4-basic: lz4 datagen unlz4 lz4cat
        $(PRGDIR)/lz4cat tmp                  # pass-through mode
        ls -ls tmp
        ls -ls tmp.lz4     && false || true   # must fail (lz4cat)
+       $(LZ4) tmp                         # creates tmp.lz4
+       $(PRGDIR)/lz4cat < tmp.lz4 > tmp3  # checks lz4cat works with stdin (#285)
+       diff -q tmp tmp3
+       $(PRGDIR)/lz4cat < tmp > tmp2      # checks lz4cat works with stdin (#285)
+       diff -q tmp tmp2
        @$(RM) tmp*
 
 test-lz4-hugefile: lz4 datagen