Skip to content

Commit 5182265

Browse files
kbleesgitster
authored andcommitted
Win32: reliably detect console pipe handles
As of "Win32: Thread-safe windows console output", child processes may print to the console even if stdout has been redirected to a file. E.g.: git config tar.cat.command "cat" git archive -o test.cat HEAD Detecting whether stdout / stderr point to our console pipe is currently based on the assumption that OS HANDLE values are never reused. This is apparently not true if stdout / stderr is replaced via dup2() (as in builtin/archive.c:17). Instead of comparing handle values, check if the file descriptor isatty() backed by a pipe OS handle. This is only possible by swapping the handles in MSVCRT's internal data structures, as we do in winansi_init(). Reported-by: Johannes Sixt <[email protected]> Signed-off-by: Karsten Blees <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent fcd428f commit 5182265

File tree

1 file changed

+7
-18
lines changed

1 file changed

+7
-18
lines changed

compat/winansi.c

Lines changed: 7 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ static WORD attr;
2020
static int negative;
2121
static int non_ascii_used = 0;
2222
static HANDLE hthread, hread, hwrite;
23-
static HANDLE hwrite1 = INVALID_HANDLE_VALUE, hwrite2 = INVALID_HANDLE_VALUE;
2423
static HANDLE hconsole1, hconsole2;
2524

2625
#ifdef __MINGW32__
@@ -435,10 +434,6 @@ static void winansi_exit(void)
435434
WaitForSingleObject(hthread, INFINITE);
436435

437436
/* cleanup handles... */
438-
if (hwrite1 != INVALID_HANDLE_VALUE)
439-
CloseHandle(hwrite1);
440-
if (hwrite2 != INVALID_HANDLE_VALUE)
441-
CloseHandle(hwrite2);
442437
CloseHandle(hwrite);
443438
CloseHandle(hthread);
444439
}
@@ -565,14 +560,9 @@ void winansi_init(void)
565560

566561
/* redirect stdout / stderr to the pipe */
567562
if (con1)
568-
hconsole1 = swap_osfhnd(1, hwrite1 = duplicate_handle(hwrite));
563+
hconsole1 = swap_osfhnd(1, duplicate_handle(hwrite));
569564
if (con2)
570-
hconsole2 = swap_osfhnd(2, hwrite2 = duplicate_handle(hwrite));
571-
}
572-
573-
static int is_same_handle(HANDLE hnd, int fd)
574-
{
575-
return hnd != INVALID_HANDLE_VALUE && hnd == (HANDLE) _get_osfhandle(fd);
565+
hconsole2 = swap_osfhnd(2, duplicate_handle(hwrite));
576566
}
577567

578568
/*
@@ -581,10 +571,9 @@ static int is_same_handle(HANDLE hnd, int fd)
581571
*/
582572
HANDLE winansi_get_osfhandle(int fd)
583573
{
584-
if (fd == 1 && is_same_handle(hwrite1, 1))
585-
return hconsole1;
586-
else if (fd == 2 && is_same_handle(hwrite2, 2))
587-
return hconsole2;
588-
else
589-
return (HANDLE) _get_osfhandle(fd);
574+
HANDLE hnd = (HANDLE) _get_osfhandle(fd);
575+
if ((fd == 1 || fd == 2) && isatty(fd)
576+
&& GetFileType(hnd) == FILE_TYPE_PIPE)
577+
return (fd == 1) ? hconsole1 : hconsole2;
578+
return hnd;
590579
}

0 commit comments

Comments
 (0)