summaryrefslogtreecommitdiff
path: root/compat
diff options
context:
space:
mode:
authorJohannes Schindelin <johannes.schindelin@gmx.de>2016-12-11 11:16:57 (GMT)
committerJunio C Hamano <gitster@pobox.com>2016-12-12 00:15:46 (GMT)
commitcbb3f3c9b1975c9bdd07f24fc4ef4e504507adaa (patch)
tree3f20d55b4ec5b38f0cf03b8452ee73955c5f559e /compat
parentc3808ca6982b0ad7ee9b87eca9b50b9a24ec08b0 (diff)
downloadgit-cbb3f3c9b1975c9bdd07f24fc4ef4e504507adaa.zip
git-cbb3f3c9b1975c9bdd07f24fc4ef4e504507adaa.tar.gz
git-cbb3f3c9b1975c9bdd07f24fc4ef4e504507adaa.tar.bz2
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.h3
-rw-r--r--compat/winansi.c33
2 files changed, 36 insertions, 0 deletions
diff --git a/compat/mingw.h b/compat/mingw.h
index 034fff9..3350169 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 db4a5b0..cb725fb 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;