From bed407a12630c0886532b4b2d54dbedd74d52d98 Mon Sep 17 00:00:00 2001 From: Ron Yorston Date: Tue, 29 Oct 2024 12:52:12 +0000 Subject: win32: more problems with stream i/o and MSVCRT These commands: cut --wrong-opt 2>&1 echo $(cut --wrong-opt 2>&1) resulted in different output. In the first case the message about the invalid option appeared before the usage message; in the second after. The command uname --wrong-opt 1>&- 2>&- displayed the error message even though both output streams were closed. These issues appear to be related to those previously fixed by commits 4be93f32f and f192e6539: - They involve the interaction between shell redirection and stream input/output. - UCRT builds aren't affected. Apply two workarounds: - When the file descriptor associated with stderr is redirected remind stderr it should be unbuffered. (32- and 64-bit MSVCRT) - When the file descriptor associated with any of the standard i/o streams is to be closed do it by closing the stream instead. (32-bit MSVCRT) Adds 48-176 bytes. (GitHub commit #472) --- shell/ash.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/shell/ash.c b/shell/ash.c index fd2a66270..a5b7dbc74 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -6542,6 +6542,12 @@ save_fd_on_redirect(int fd, int avoid_fd, struct redirtab *sq) if (fd == preverrout_fd) preverrout_fd = new_fd; +#if ENABLE_PLATFORM_MINGW32 && !defined(_UCRT) + // Workaround for problems with stderr in MSVCRT + if (fd == fileno(stderr)) + setvbuf(stderr, NULL, _IONBF, 0); +#endif + return 0; /* "we did not close fd" */ } @@ -6629,6 +6635,16 @@ redirect(union node *redir, int flags) if (!closed) { /* ^^^ optimization: saving may already * have closed it. If not... */ +#if ENABLE_PLATFORM_MINGW32 && !defined(_UCRT) && !defined(_WIN64) + // Workaround for problems with streams in 32-bit MSVCRT + if (fd == fileno(stdin)) + fclose(stdin); + else if (fd == fileno(stdout)) + fclose(stdout); + else if (fd == fileno(stderr)) + fclose(stderr); + else +#endif close(fd); } } else { -- cgit v1.2.3-55-g6feb