Skip to content

Commit 1676827

Browse files
committed
Merge branch 'kb/msys2-tty' into maint
The "are we talking with TTY, doing an interactive session?" detection has been updated to work better for "Git for Windows". * kb/msys2-tty: mingw: make isatty() recognize MSYS2's pseudo terminals (/dev/pty*)
2 parents 389c328 + f7f90e0 commit 1676827

File tree

2 files changed

+56
-5
lines changed

2 files changed

+56
-5
lines changed

compat/winansi.c

+54-4
Original file line numberDiff line numberDiff line change
@@ -483,6 +483,7 @@ static size_t sizeof_ioinfo = 0;
483483
#define IOINFO_L2E 5
484484
#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
485485

486+
#define FPIPE 0x08
486487
#define FDEV 0x40
487488

488489
static inline ioinfo* _pioinfo(int fd)
@@ -530,6 +531,45 @@ static HANDLE swap_osfhnd(int fd, HANDLE new_handle)
530531
return old_handle;
531532
}
532533

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 MSYS2 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+
533573
void winansi_init(void)
534574
{
535575
int con1, con2;
@@ -538,8 +578,15 @@ void winansi_init(void)
538578
/* check if either stdout or stderr is a console output screen buffer */
539579
con1 = is_console(1);
540580
con2 = is_console(2);
541-
if (!con1 && !con2)
581+
if (!con1 && !con2) {
582+
#ifdef DETECT_MSYS_TTY
583+
/* check if stdin / stdout / stderr are MSYS2 pty pipes */
584+
detect_msys_tty(0);
585+
detect_msys_tty(1);
586+
detect_msys_tty(2);
587+
#endif
542588
return;
589+
}
543590

544591
/* create a named pipe to communicate with the console thread */
545592
xsnprintf(name, sizeof(name), "\\\\.\\pipe\\winansi%lu", GetCurrentProcessId());
@@ -575,8 +622,11 @@ void winansi_init(void)
575622
HANDLE winansi_get_osfhandle(int fd)
576623
{
577624
HANDLE hnd = (HANDLE) _get_osfhandle(fd);
578-
if ((fd == 1 || fd == 2) && isatty(fd)
579-
&& GetFileType(hnd) == FILE_TYPE_PIPE)
580-
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+
}
581631
return hnd;
582632
}

config.mak.uname

+2-1
Original file line numberDiff line numberDiff line change
@@ -557,7 +557,8 @@ else
557557
BASIC_LDFLAGS += -Wl,--large-address-aware
558558
endif
559559
CC = gcc
560-
COMPAT_CFLAGS += -D__USE_MINGW_ANSI_STDIO=0
560+
COMPAT_CFLAGS += -D__USE_MINGW_ANSI_STDIO=0 -DDETECT_MSYS_TTY
561+
EXTLIBS += -lntdll
561562
INSTALL = /bin/install
562563
NO_R_TO_GCC_LINKER = YesPlease
563564
INTERNAL_QSORT = YesPlease

0 commit comments

Comments
 (0)