Skip to content

Commit 14f6c21

Browse files
committed
Merge pull request #102 from kb/msys-tty
Better MSys PTY detection Signed-off-by: Johannes Schindelin <[email protected]>
2 parents ca15bb6 + ba20c83 commit 14f6c21

File tree

4 files changed

+56
-47
lines changed

4 files changed

+56
-47
lines changed

compat/mingw.c

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

9-
#undef isatty
10-
119
#define HCAST(type, handle) ((type)(intptr_t)handle)
1210

1311
static const int delay[] = { 0, 1, 10, 20, 40 };
@@ -2380,38 +2378,3 @@ void mingw_startup()
23802378
/* init length of current directory for handle_long_path */
23812379
current_directory_len = GetCurrentDirectoryW(0, NULL);
23822380
}
2383-
2384-
int mingw_isatty(int fd) {
2385-
static DWORD id[] = {
2386-
STD_INPUT_HANDLE,
2387-
STD_OUTPUT_HANDLE,
2388-
STD_ERROR_HANDLE
2389-
};
2390-
static unsigned initialized;
2391-
static int is_tty[ARRAY_SIZE(id)];
2392-
2393-
if (fd < 0 || fd >= ARRAY_SIZE(is_tty))
2394-
return isatty(fd);
2395-
2396-
if (isatty(fd))
2397-
return 1;
2398-
2399-
if (!initialized) {
2400-
const char *env = getenv("MSYS_TTY_HANDLES");
2401-
2402-
if (env) {
2403-
int i;
2404-
char buffer[64];
2405-
2406-
for (i = 0; i < ARRAY_SIZE(is_tty); i++) {
2407-
sprintf(buffer, " %" PRIuMAX " ",
2408-
HCAST(uintmax_t, GetStdHandle(id[i])));
2409-
is_tty[i] = !!strstr(env, buffer);
2410-
}
2411-
}
2412-
2413-
initialized = 1;
2414-
}
2415-
2416-
return is_tty[fd];
2417-
}

compat/mingw.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -367,9 +367,6 @@ 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-
373370
/*
374371
* ANSI emulation wrappers
375372
*/

compat/winansi.c

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

10-
#undef isatty
11-
1210
/*
1311
ANSI codes used by git: m, K
1412
@@ -485,6 +483,7 @@ static size_t sizeof_ioinfo = 0;
485483
#define IOINFO_L2E 5
486484
#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
487485

486+
#define FPIPE 0x08
488487
#define FDEV 0x40
489488

490489
static inline ioinfo* _pioinfo(int fd)
@@ -532,6 +531,45 @@ static HANDLE swap_osfhnd(int fd, HANDLE new_handle)
532531
return old_handle;
533532
}
534533

534+
#ifdef DETECT_MSYS_TTY
535+
536+
#include <winternl.h>
537+
#include <ntstatus.h>
538+
539+
static void detect_msys_tty(int fd)
540+
{
541+
ULONG result;
542+
BYTE buffer[1024];
543+
POBJECT_NAME_INFORMATION nameinfo = (POBJECT_NAME_INFORMATION) buffer;
544+
PWSTR name;
545+
546+
/* check if fd is a pipe */
547+
HANDLE h = (HANDLE) _get_osfhandle(fd);
548+
if (GetFileType(h) != FILE_TYPE_PIPE)
549+
return;
550+
551+
/* get pipe name */
552+
if (!NT_SUCCESS(NtQueryObject(h, ObjectNameInformation,
553+
buffer, sizeof(buffer) - 2, &result)))
554+
return;
555+
name = nameinfo->Name.Buffer;
556+
name[nameinfo->Name.Length] = 0;
557+
558+
/* check if this could be a msys pty pipe ('msys-XXXX-ptyN-XX') */
559+
if (!wcsstr(name, L"msys-") || !wcsstr(name, L"-pty"))
560+
return;
561+
562+
/* init ioinfo size if we haven't done so */
563+
if (init_sizeof_ioinfo())
564+
return;
565+
566+
/* set FDEV flag, reset FPIPE flag */
567+
_pioinfo(fd)->osflags &= ~FPIPE;
568+
_pioinfo(fd)->osflags |= FDEV;
569+
}
570+
571+
#endif
572+
535573
void winansi_init(void)
536574
{
537575
int con1, con2;
@@ -540,8 +578,15 @@ void winansi_init(void)
540578
/* check if either stdout or stderr is a console output screen buffer */
541579
con1 = is_console(1);
542580
con2 = is_console(2);
543-
if (!con1 && !con2)
581+
if (!con1 && !con2) {
582+
#ifdef DETECT_MSYS_TTY
583+
/* check if stdin / stdout / stderr are msys pty pipes */
584+
detect_msys_tty(0);
585+
detect_msys_tty(1);
586+
detect_msys_tty(2);
587+
#endif
544588
return;
589+
}
545590

546591
/* create a named pipe to communicate with the console thread */
547592
sprintf(name, "\\\\.\\pipe\\winansi%lu", GetCurrentProcessId());
@@ -577,8 +622,11 @@ void winansi_init(void)
577622
HANDLE winansi_get_osfhandle(int fd)
578623
{
579624
HANDLE hnd = (HANDLE) _get_osfhandle(fd);
580-
if ((fd == 1 || fd == 2) && isatty(fd)
581-
&& GetFileType(hnd) == FILE_TYPE_PIPE)
582-
return (fd == 1) ? hconsole1 : hconsole2;
625+
if (isatty(fd) && GetFileType(hnd) == FILE_TYPE_PIPE) {
626+
if (fd == 1 && hconsole1)
627+
return hconsole1;
628+
else if (fd == 2 && hconsole2)
629+
return hconsole2;
630+
}
583631
return hnd;
584632
}

config.mak.uname

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -548,7 +548,8 @@ else
548548
BASIC_LDFLAGS += -Wl,--large-address-aware
549549
endif
550550
CC = gcc
551-
COMPAT_CFLAGS += -D__USE_MINGW_ANSI_STDIO=0
551+
COMPAT_CFLAGS += -D__USE_MINGW_ANSI_STDIO=0 -DDETECT_MSYS_TTY
552+
EXTLIBS += -lntdll
552553
INSTALL = /bin/install
553554
NO_R_TO_GCC_LINKER = YesPlease
554555
INTERNAL_QSORT = YesPlease

0 commit comments

Comments
 (0)