diff options
author | Johannes Schindelin <johannes.schindelin@gmx.de> | 2016-12-11 12:16:57 +0100 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2016-12-11 16:15:46 -0800 |
commit | cbb3f3c9b1975c9bdd07f24fc4ef4e504507adaa (patch) | |
tree | 3f20d55b4ec5b38f0cf03b8452ee73955c5f559e /compat | |
parent | preparing for 2.10.3 (diff) | |
download | tgif-cbb3f3c9b1975c9bdd07f24fc4ef4e504507adaa.tar.xz |
mingw: intercept isatty() to handle /dev/null as Git expects it
When Git's source code calls isatty(), it really asks whether the
respective file descriptor is connected to an interactive terminal.
Windows' _isatty() function, however, determines whether the file
descriptor is associated with a character device. And NUL, Windows'
equivalent of /dev/null, is a character device.
Which means that for years, Git mistakenly detected an associated
interactive terminal when being run through the test suite, which
almost always redirects stdin, stdout and stderr to /dev/null.
This bug only became obvious, and painfully so, when the new
bisect--helper entered the `pu` branch and made the automatic build & test
time out because t6030 was waiting for an answer.
For details, see
https://msdn.microsoft.com/en-us/library/f4s0ddew.aspx
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'compat')
-rw-r--r-- | compat/mingw.h | 3 | ||||
-rw-r--r-- | compat/winansi.c | 33 |
2 files changed, 36 insertions, 0 deletions
diff --git a/compat/mingw.h b/compat/mingw.h index 034fff9479..3350169555 100644 --- a/compat/mingw.h +++ b/compat/mingw.h @@ -384,6 +384,9 @@ int mingw_raise(int sig); * ANSI emulation wrappers */ +int winansi_isatty(int fd); +#define isatty winansi_isatty + void winansi_init(void); HANDLE winansi_get_osfhandle(int fd); diff --git a/compat/winansi.c b/compat/winansi.c index db4a5b0a37..cb725fb02f 100644 --- a/compat/winansi.c +++ b/compat/winansi.c @@ -7,6 +7,9 @@ #include <wingdi.h> #include <winreg.h> +/* In this file, we actually want to use Windows' own isatty(). */ +#undef isatty + /* ANSI codes used by git: m, K @@ -570,6 +573,36 @@ static void detect_msys_tty(int fd) #endif +int winansi_isatty(int fd) +{ + int res = isatty(fd); + + if (res) { + /* + * Make sure that /dev/null is not fooling Git into believing + * that we are connected to a terminal, as "_isatty() returns a + * nonzero value if the descriptor is associated with a + * character device."; for more information, see + * + * https://msdn.microsoft.com/en-us/library/f4s0ddew.aspx + */ + HANDLE handle = (HANDLE)_get_osfhandle(fd); + if (fd == STDIN_FILENO) { + DWORD dummy; + + if (!GetConsoleMode(handle, &dummy)) + res = 0; + } else if (fd == STDOUT_FILENO || fd == STDERR_FILENO) { + CONSOLE_SCREEN_BUFFER_INFO dummy; + + if (!GetConsoleScreenBufferInfo(handle, &dummy)) + res = 0; + } + } + + return res; +} + void winansi_init(void) { int con1, con2; |