From: Karsten Blees <bl...@dcon.de>

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 <bl...@dcon.de>
Signed-off-by: Johannes Schindelin <johannes.schinde...@gmx.de>
Signed-off-by: Stepan Kasal <ka...@ucw.cz>
---
 compat/winansi.c | 50 ++++++++++++++++++++++++++------------------------
 1 file changed, 26 insertions(+), 24 deletions(-)

diff --git a/compat/winansi.c b/compat/winansi.c
index abe0fea..c4be401 100644
--- a/compat/winansi.c
+++ b/compat/winansi.c
@@ -25,27 +25,39 @@ static HANDLE console;
 static WORD plain_attr;
 static WORD attr;
 static int negative;
+static FILE *last_stream = NULL;
 
-static void init(void)
+static int is_console(FILE *stream)
 {
        CONSOLE_SCREEN_BUFFER_INFO sbi;
+       HANDLE hcon;
 
        static int initialized = 0;
-       if (initialized)
-               return;
 
-       console = GetStdHandle(STD_OUTPUT_HANDLE);
-       if (console == INVALID_HANDLE_VALUE)
-               console = NULL;
+       /* use cached value if stream hasn't changed */
+       if (stream == last_stream)
+               return console != NULL;
 
-       if (!console)
-               return;
+       last_stream = stream;
+       console = NULL;
 
-       GetConsoleScreenBufferInfo(console, &sbi);
-       attr = plain_attr = sbi.wAttributes;
-       negative = 0;
+       /* get OS handle of the stream */
+       hcon = (HANDLE) _get_osfhandle(_fileno(stream));
+       if (hcon == INVALID_HANDLE_VALUE)
+               return 0;
+
+       /* check if its a handle to a console output screen buffer */
+       if (!GetConsoleScreenBufferInfo(hcon, &sbi))
+               return 0;
+
+       if (!initialized) {
+               attr = plain_attr = sbi.wAttributes;
+               negative = 0;
+               initialized = 1;
+       }
 
-       initialized = 1;
+       console = hcon;
+       return 1;
 }
 
 static int write_console(const char *str, size_t len)
@@ -292,12 +304,7 @@ int winansi_fputs(const char *str, FILE *stream)
 {
        int rv;
 
-       if (!isatty(fileno(stream)))
-               return fputs(str, stream);
-
-       init();
-
-       if (!console)
+       if (!is_console(stream))
                return fputs(str, stream);
 
        rv = ansi_emulate(str, stream);
@@ -315,12 +322,7 @@ int winansi_vfprintf(FILE *stream, const char *format, 
va_list list)
        char *buf = small_buf;
        va_list cp;
 
-       if (!isatty(fileno(stream)))
-               goto abort;
-
-       init();
-
-       if (!console)
+       if (!is_console(stream))
                goto abort;
 
        va_copy(cp, list);
-- 
2.0.0.9635.g0be03cb

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to