Skip to content

Commit 143e615

Browse files
kbleesgitster
authored andcommitted
Win32: detect console streams more reliably
GetStdHandle(STD_OUTPUT_HANDLE) doesn't work for stderr if stdout is redirected. Use _get_osfhandle of the FILE* instead. _isatty() is true for all character devices (including parallel and serial ports). Check return value of GetConsoleScreenBufferInfo instead to reliably detect console handles (also don't initialize internal state from an uninitialized CONSOLE_SCREEN_BUFFER_INFO structure if the function fails). Signed-off-by: Karsten Blees <[email protected]> Signed-off-by: Johannes Schindelin <[email protected]> Signed-off-by: Stepan Kasal <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 617ce96 commit 143e615

File tree

1 file changed

+26
-24
lines changed

1 file changed

+26
-24
lines changed

compat/winansi.c

Lines changed: 26 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -25,27 +25,39 @@ static HANDLE console;
2525
static WORD plain_attr;
2626
static WORD attr;
2727
static int negative;
28+
static FILE *last_stream = NULL;
2829

29-
static void init(void)
30+
static int is_console(FILE *stream)
3031
{
3132
CONSOLE_SCREEN_BUFFER_INFO sbi;
33+
HANDLE hcon;
3234

3335
static int initialized = 0;
34-
if (initialized)
35-
return;
3636

37-
console = GetStdHandle(STD_OUTPUT_HANDLE);
38-
if (console == INVALID_HANDLE_VALUE)
39-
console = NULL;
37+
/* use cached value if stream hasn't changed */
38+
if (stream == last_stream)
39+
return console != NULL;
4040

41-
if (!console)
42-
return;
41+
last_stream = stream;
42+
console = NULL;
4343

44-
GetConsoleScreenBufferInfo(console, &sbi);
45-
attr = plain_attr = sbi.wAttributes;
46-
negative = 0;
44+
/* get OS handle of the stream */
45+
hcon = (HANDLE) _get_osfhandle(_fileno(stream));
46+
if (hcon == INVALID_HANDLE_VALUE)
47+
return 0;
48+
49+
/* check if its a handle to a console output screen buffer */
50+
if (!GetConsoleScreenBufferInfo(hcon, &sbi))
51+
return 0;
52+
53+
if (!initialized) {
54+
attr = plain_attr = sbi.wAttributes;
55+
negative = 0;
56+
initialized = 1;
57+
}
4758

48-
initialized = 1;
59+
console = hcon;
60+
return 1;
4961
}
5062

5163
static int write_console(const char *str, size_t len)
@@ -292,12 +304,7 @@ int winansi_fputs(const char *str, FILE *stream)
292304
{
293305
int rv;
294306

295-
if (!isatty(fileno(stream)))
296-
return fputs(str, stream);
297-
298-
init();
299-
300-
if (!console)
307+
if (!is_console(stream))
301308
return fputs(str, stream);
302309

303310
rv = ansi_emulate(str, stream);
@@ -315,12 +322,7 @@ int winansi_vfprintf(FILE *stream, const char *format, va_list list)
315322
char *buf = small_buf;
316323
va_list cp;
317324

318-
if (!isatty(fileno(stream)))
319-
goto abort;
320-
321-
init();
322-
323-
if (!console)
325+
if (!is_console(stream))
324326
goto abort;
325327

326328
va_copy(cp, list);

0 commit comments

Comments
 (0)