Skip to content

Commit cbb3f3c

Browse files
dschogitster
authored andcommitted
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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent c3808ca commit cbb3f3c

File tree

2 files changed

+36
-0
lines changed

2 files changed

+36
-0
lines changed

compat/mingw.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,9 @@ int mingw_raise(int sig);
384384
* ANSI emulation wrappers
385385
*/
386386

387+
int winansi_isatty(int fd);
388+
#define isatty winansi_isatty
389+
387390
void winansi_init(void);
388391
HANDLE winansi_get_osfhandle(int fd);
389392

compat/winansi.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77
#include <wingdi.h>
88
#include <winreg.h>
99

10+
/* In this file, we actually want to use Windows' own isatty(). */
11+
#undef isatty
12+
1013
/*
1114
ANSI codes used by git: m, K
1215
@@ -570,6 +573,36 @@ static void detect_msys_tty(int fd)
570573

571574
#endif
572575

576+
int winansi_isatty(int fd)
577+
{
578+
int res = isatty(fd);
579+
580+
if (res) {
581+
/*
582+
* Make sure that /dev/null is not fooling Git into believing
583+
* that we are connected to a terminal, as "_isatty() returns a
584+
* nonzero value if the descriptor is associated with a
585+
* character device."; for more information, see
586+
*
587+
* https://msdn.microsoft.com/en-us/library/f4s0ddew.aspx
588+
*/
589+
HANDLE handle = (HANDLE)_get_osfhandle(fd);
590+
if (fd == STDIN_FILENO) {
591+
DWORD dummy;
592+
593+
if (!GetConsoleMode(handle, &dummy))
594+
res = 0;
595+
} else if (fd == STDOUT_FILENO || fd == STDERR_FILENO) {
596+
CONSOLE_SCREEN_BUFFER_INFO dummy;
597+
598+
if (!GetConsoleScreenBufferInfo(handle, &dummy))
599+
res = 0;
600+
}
601+
}
602+
603+
return res;
604+
}
605+
573606
void winansi_init(void)
574607
{
575608
int con1, con2;

0 commit comments

Comments
 (0)