[commit: ghc] master: Properly detect MinTTY when running GHCi on Windows (6fe9b05)

git at git.haskell.org git at git.haskell.org
Tue Jan 10 19:21:53 UTC 2017


Repository : ssh://git@git.haskell.org/ghc

On branch  : master
Link       : http://ghc.haskell.org/trac/ghc/changeset/6fe9b057396b4ace73106dc9c3c7fcb72a216bfa/ghc

>---------------------------------------------------------------

commit 6fe9b057396b4ace73106dc9c3c7fcb72a216bfa
Author: Ryan Scott <ryan.gl.scott at gmail.com>
Date:   Thu Jan 5 17:03:19 2017 -0500

    Properly detect MinTTY when running GHCi on Windows
    
    Before, we detecting the presence of MinTTY on Windows in a very
    imprecise way: by checking if the `_` environment variable was set. Not
    only is this easy to circumvent, but it also yields false positives on
    terminals like ConEmu.
    
    This changes the test to use the `GetFileInformationByHandleEx` function
    instead, which provides a far more accurate check for MinTTY's presence.
    I've tested this on PowerShell, MSYS2, Cygwin, ConEmu, and Git Bash, and
    it does the right thing on each one.
    
    Fixes #12958.
    
    Test Plan: Run GHCi on many different Windows and MinTTY consoles
    
    Reviewers: erikd, Phyx, austin, bgamari
    
    Reviewed By: Phyx, bgamari
    
    Subscribers: thomie, #ghc_windows_task_force
    
    Differential Revision: https://phabricator.haskell.org/D2878
    
    GHC Trac Issues: #12958


>---------------------------------------------------------------

6fe9b057396b4ace73106dc9c3c7fcb72a216bfa
 driver/ghci/ghc.mk      |  2 +-
 driver/ghci/ghci.c      |  5 +++--
 driver/utils/isMinTTY.c | 33 +++++++++++++++++++++++++++++++++
 driver/utils/isMinTTY.h |  8 ++++++++
 4 files changed, 45 insertions(+), 3 deletions(-)

diff --git a/driver/ghci/ghc.mk b/driver/ghci/ghc.mk
index 240e16f..41d1f15 100644
--- a/driver/ghci/ghc.mk
+++ b/driver/ghci/ghc.mk
@@ -29,7 +29,7 @@ install_driver_ghci:
 
 else # Windows_Host...
 
-driver/ghci_dist_C_SRCS  = ghci.c ../utils/cwrapper.c ../utils/getLocation.c
+driver/ghci_dist_C_SRCS  = ghci.c ../utils/cwrapper.c ../utils/getLocation.c ../utils/isMinTTY.c
 driver/ghci_dist_CC_OPTS += -I driver/utils
 driver/ghci_dist_PROGNAME = ghci
 driver/ghci_dist_INSTALL = YES
diff --git a/driver/ghci/ghci.c b/driver/ghci/ghci.c
index f358d96..ebf13d8 100644
--- a/driver/ghci/ghci.c
+++ b/driver/ghci/ghci.c
@@ -1,6 +1,7 @@
 
 #include "cwrapper.h"
 #include "getLocation.h"
+#include "isMinTTY.h"
 #include <stdio.h>
 #include <stdlib.h>
 #include <windows.h>
@@ -15,8 +16,8 @@ int main(int argc, char** argv) {
     char *exePath;
     char *preArgv[1];
 
-    if (getenv("_")) {
-        printf("WARNING: GHCi invoked via 'ghci.exe' in *nix-like shells (cygwin-bash, in particular)\n");
+    if (isMinTTY()) {
+        printf("WARNING: GHCi invoked via 'ghci.exe' in MinTTY consoles (e.g., Cygwin or MSYS)\n");
         printf("         doesn't handle Ctrl-C well; use the 'ghcii.sh' shell wrapper instead\n");
         fflush(stdout);
     }
diff --git a/driver/utils/isMinTTY.c b/driver/utils/isMinTTY.c
new file mode 100644
index 0000000..3b3ae27
--- /dev/null
+++ b/driver/utils/isMinTTY.c
@@ -0,0 +1,33 @@
+/*
+ * We need Vista headers to use the GetFileInformationByHandleEx function and
+ * the FILE_NAME_INFO struct.
+ */
+#define WINVER 0x0600
+#define _WIN32_WINNT 0x0600
+
+#include <stdbool.h>
+#include <windows.h>
+#include "isMINTTY.h"
+
+bool isMinTTY() {
+  const HANDLE h = GetStdHandle(STD_ERROR_HANDLE);
+  if (h == NULL || h == INVALID_HANDLE_VALUE) {
+    return false;
+  } else if (GetFileType(h) != FILE_TYPE_PIPE) {
+    return false;
+  }
+
+  const unsigned long bufSize = sizeof(DWORD) + MAX_PATH * sizeof(WCHAR);
+  BYTE buf[bufSize];
+  PFILE_NAME_INFO pfni = (PFILE_NAME_INFO) buf;
+
+  if (!GetFileInformationByHandleEx(h, FileNameInfo, buf, bufSize)) {
+    return false;
+  }
+
+  PWSTR fn = pfni->FileName;
+  fn[pfni->FileNameLength] = L'\0';
+
+  return ((wcsstr(fn, L"\\cygwin-") || wcsstr(fn, L"\\msys-")) &&
+           wcsstr(fn, L"-pty") && wcsstr(fn, L"-master"));
+}
diff --git a/driver/utils/isMinTTY.h b/driver/utils/isMinTTY.h
new file mode 100644
index 0000000..22e9a47
--- /dev/null
+++ b/driver/utils/isMinTTY.h
@@ -0,0 +1,8 @@
+#ifndef ISMINTTY_H
+#define ISMINTTY_H
+
+#include <stdbool.h>
+
+bool isMinTTY();
+
+#endif /* ISMINTTY_H */



More information about the ghc-commits mailing list