Skip to content

Commit de0d35d

Browse files
committed
mingw: Work around MSVCRT's isatty() not knowing about MSys2
MSys2 has a slightly different notion of what constitutes a tty than the Microsoft C runtime. The former knows whether stdin/stdout/stderr was redirected or not, while the latter looks for a Win32 Console. In particular when we want to know whether to spawn a pager or not, we would rather want to know what MSys2 thinks. We are about to introduce a change to the msys2-runtime that sets an environment variable MSYS_TTY_HANDLES to a list of Win32 handles that correspond to stdin/stdout/stderr, respectively, *but skips* handles that MSys2 does not think are terminals. This commit handles that input to augment the isatty() function to return 1 also when MSYS_TTY_HANDLES contains the corresponding handle. The only time when Git needs to know whether a Console is attached or not is when winansi.c is asked to Do Its Thing, therefore we refrain from overriding isatty there. Note: this was an issue with MSys1-based Git for Windows, too, hidden by the fact that Git for Windows used `cmd.exe` as a terminal -- which is backed by a real Win32 Console. Had MSys1 used, say, rxvt as its default terminal, the symptom would have been that "git log" does not spawn a pager by default but instead outputs the entire history (without color coding, too). In MSys2, the default terminal is mintty, therefore we finally could not avoid to address the issue. Signed-off-by: Johannes Schindelin <[email protected]>
1 parent 3f560bc commit de0d35d

File tree

3 files changed

+42
-0
lines changed

3 files changed

+42
-0
lines changed

compat/mingw.c

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
#include "../run-command.h"
77
#include "../cache.h"
88

9+
#undef isatty
10+
911
static const int delay[] = { 0, 1, 10, 20, 40 };
1012
unsigned int _CRT_fmode = _O_BINARY;
1113

@@ -2287,3 +2289,38 @@ void mingw_startup()
22872289
/* init length of current directory for handle_long_path */
22882290
current_directory_len = GetCurrentDirectoryW(0, NULL);
22892291
}
2292+
2293+
int mingw_isatty(int fd) {
2294+
static DWORD id[] = {
2295+
STD_INPUT_HANDLE,
2296+
STD_OUTPUT_HANDLE,
2297+
STD_ERROR_HANDLE
2298+
};
2299+
static unsigned initialized;
2300+
static int is_tty[ARRAY_SIZE(id)];
2301+
2302+
if (fd < 0 || fd >= ARRAY_SIZE(is_tty))
2303+
return isatty(fd);
2304+
2305+
if (isatty(fd))
2306+
return 1;
2307+
2308+
if (!initialized) {
2309+
const char *env = getenv("MSYS_TTY_HANDLES");
2310+
2311+
if (env) {
2312+
int i;
2313+
char buffer[64];
2314+
2315+
for (i = 0; i < ARRAY_SIZE(is_tty); i++) {
2316+
sprintf(buffer, " %ld ", (unsigned long)
2317+
GetStdHandle(id[i]));
2318+
is_tty[i] = !!strstr(env, buffer);
2319+
}
2320+
}
2321+
2322+
initialized = 1;
2323+
}
2324+
2325+
return is_tty[fd];
2326+
}

compat/mingw.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,9 @@ sig_handler_t mingw_signal(int sig, sig_handler_t handler);
367367
int mingw_raise(int sig);
368368
#define raise mingw_raise
369369

370+
int mingw_isatty(int fd);
371+
#define isatty mingw_isatty
372+
370373
/*
371374
* ANSI emulation wrappers
372375
*/

compat/winansi.c

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

10+
#undef isatty
11+
1012
/*
1113
ANSI codes used by git: m, K
1214

0 commit comments

Comments
 (0)