]> git.ipfire.org Git - thirdparty/xz.git/commitdiff
Windows: Avoid an error message on broken pipe
authorLasse Collin <lasse.collin@tukaani.org>
Tue, 28 Jan 2025 14:28:18 +0000 (16:28 +0200)
committerLasse Collin <lasse.collin@tukaani.org>
Wed, 29 Jan 2025 18:59:44 +0000 (20:59 +0200)
Also make xz not process more input files after a broken pipe has
been detected. This matches the behavior on POSIX. If all files
are being written to standard output, trying with the next file is
pointless when it's known that standard output won't accept more data.

xzdec already stopped after the first error. It does so with all
errors, so it differs from xz:

    $ xz -dc not_found_1 not_found_2
    xz: not_found_1: No such file or directory
    xz: not_found_2: No such file or directory

    $ xzdec not_found_1 not_found_2
    xzdec: not_found_1: No such file or directory

Reported-by: Vincent Torri
src/xz/file_io.c
src/xzdec/xzdec.c

index 97d6b40102e0527d3a342a6c2fd65ae183c69c51..8c83269b13fa31284f7ea5f3627a1dfbce7d6e14 100644 (file)
@@ -1390,6 +1390,19 @@ io_write_buf(file_pair *pair, const uint8_t *buf, size_t size)
                        }
 #endif
 
+#if defined(_WIN32) && !defined(__CYGWIN__)
+                       // On native Windows, broken pipe is reported as
+                       // EINVAL. Don't show an error message in this case.
+                       // Try: xz -dc bigfile.xz | head -n1
+                       if (errno == EINVAL
+                                       && pair->dest_fd == STDOUT_FILENO) {
+                               // Emulate SIGPIPE by setting user_abort here.
+                               user_abort = true;
+                               set_exit_status(E_ERROR);
+                               return true;
+                       }
+#endif
+
                        // Handle broken pipe specially. gzip and bzip2
                        // don't print anything on SIGPIPE. In addition,
                        // gzip --quiet uses exit status 2 (warning) on
index 8413421374af064f18be83065726d9fed68668fc..96e2444438c203e18f9b2577ec3423b40a08ffba 100644 (file)
@@ -230,8 +230,17 @@ uncompress(lzma_stream *strm, FILE *file, const char *filename)
                                // Wouldn't be a surprise if writing to stderr
                                // would fail too but at least try to show an
                                // error message.
-                               my_errorf("Cannot write to standard output: "
+#if defined(_WIN32) && !defined(__CYGWIN__)
+                               // On native Windows, broken pipe is reported
+                               // as EINVAL. Don't show an error message
+                               // in this case.
+                               if (errno != EINVAL)
+#endif
+                               {
+                                       my_errorf("Cannot write to "
+                                               "standard output: "
                                                "%s", strerror(errno));
+                               }
                                exit(EXIT_FAILURE);
                        }