mingw: fix colourization on Cygwin pseudo terminals
[gitweb.git] / compat / winansi.c
index db4a5b0a37d687218ab085f22b57eb35e28893b8..fa37695fcaadb426ad3c933d6d987a244edb889a 100644 (file)
@@ -7,6 +7,9 @@
 #include <wingdi.h>
 #include <winreg.h>
 
+/* In this file, we actually want to use Windows' own isatty(). */
+#undef isatty
+
 /*
  ANSI codes used by git: m, K
 
@@ -81,6 +84,7 @@ static void warn_if_raster_font(void)
 static int is_console(int fd)
 {
        CONSOLE_SCREEN_BUFFER_INFO sbi;
+       DWORD mode;
        HANDLE hcon;
 
        static int initialized = 0;
@@ -95,7 +99,10 @@ static int is_console(int fd)
                return 0;
 
        /* check if its a handle to a console output screen buffer */
-       if (!GetConsoleScreenBufferInfo(hcon, &sbi))
+       if (!fd) {
+               if (!GetConsoleMode(hcon, &mode))
+                       return 0;
+       } else if (!GetConsoleScreenBufferInfo(hcon, &sbi))
                return 0;
 
        /* initialize attributes */
@@ -555,8 +562,12 @@ static void detect_msys_tty(int fd)
        name = nameinfo->Name.Buffer;
        name[nameinfo->Name.Length] = 0;
 
-       /* check if this could be a MSYS2 pty pipe ('msys-XXXX-ptyN-XX') */
-       if (!wcsstr(name, L"msys-") || !wcsstr(name, L"-pty"))
+       /*
+        * Check if this could be a MSYS2 pty pipe ('msys-XXXX-ptyN-XX')
+        * or a cygwin pty pipe ('cygwin-XXXX-ptyN-XX')
+        */
+       if ((!wcsstr(name, L"msys-") && !wcsstr(name, L"cygwin-")) ||
+                       !wcsstr(name, L"-pty"))
                return;
 
        /* init ioinfo size if we haven't done so */
@@ -570,6 +581,36 @@ static void detect_msys_tty(int fd)
 
 #endif
 
+int winansi_isatty(int fd)
+{
+       int res = isatty(fd);
+
+       if (res) {
+               /*
+                * Make sure that /dev/null is not fooling Git into believing
+                * that we are connected to a terminal, as "_isatty() returns a
+                * nonzero value if the descriptor is associated with a
+                * character device."; for more information, see
+                *
+                * https://msdn.microsoft.com/en-us/library/f4s0ddew.aspx
+                */
+               HANDLE handle = (HANDLE)_get_osfhandle(fd);
+               if (fd == STDIN_FILENO) {
+                       DWORD dummy;
+
+                       if (!GetConsoleMode(handle, &dummy))
+                               res = 0;
+               } else if (fd == STDOUT_FILENO || fd == STDERR_FILENO) {
+                       CONSOLE_SCREEN_BUFFER_INFO dummy;
+
+                       if (!GetConsoleScreenBufferInfo(handle, &dummy))
+                               res = 0;
+               }
+       }
+
+       return res;
+}
+
 void winansi_init(void)
 {
        int con1, con2;