From: Dustin L. Howett Date: Tue, 4 Jun 2024 03:27:29 +0000 (-0500) Subject: Fix tar -w on Windows (#2219) X-Git-Tag: v3.7.5~48 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6c467b7753fa8bd2c22dda280802d057ac06d9cc;p=thirdparty%2Flibarchive.git Fix tar -w on Windows (#2219) 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 --- diff --git a/tar/util.c b/tar/util.c index 37c3a2323..85060461c 100644 --- a/tar/util.c +++ b/tar/util.c @@ -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);