]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
Fix tar -w on Windows (#2219)
authorDustin L. Howett <dustin@howett.net>
Tue, 4 Jun 2024 03:27:29 +0000 (22:27 -0500)
committerGitHub <noreply@github.com>
Tue, 4 Jun 2024 03:27:29 +0000 (20:27 -0700)
The tar utility reads from stderr to receive user input even when stdin
is a pipe. That is unfortunately unsupported on Windows.

The nearest equivalent is to reopen and read from the console input
handle.

Closes #2215

tar/util.c

index 37c3a23231bd7f87afe9a76fd892d3249f8426df..85060461cc7f036a5704488f9e14b31a17df1e4e 100644 (file)
@@ -234,6 +234,7 @@ yes(const char *fmt, ...)
        char buff[32];
        char *p;
        ssize_t l;
+       int read_fd = 2; /* stderr */
 
        va_list ap;
        va_start(ap, fmt);
@@ -242,7 +243,24 @@ yes(const char *fmt, ...)
        fprintf(stderr, " (y/N)? ");
        fflush(stderr);
 
-       l = read(2, buff, sizeof(buff) - 1);
+#if defined(_WIN32) && !defined(__CYGWIN__)
+       /* To be resilient when stdin is a pipe, bsdtar prefers to read from
+        * stderr.  On Windows, stderr cannot be read. The nearest "piping
+        * resilient" equivalent is reopening the console input handle.
+        */
+       read_fd = _open("CONIN$", O_RDONLY);
+       if (read_fd < 0) {
+         fprintf(stderr, "Keyboard read failed\n");
+         exit(1);
+       }
+#endif
+
+       l = read(read_fd, buff, sizeof(buff) - 1);
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+       _close(read_fd);
+#endif
+
        if (l < 0) {
          fprintf(stderr, "Keyboard read failed\n");
          exit(1);