Index: runtime/bin/platform_win.cc |
diff --git a/runtime/bin/platform_win.cc b/runtime/bin/platform_win.cc |
index 71a274346d439320e45cbe43a029e26a2cf21091..e34d515963d8bc9cf69a58c1e10f44c3d9b583a7 100644 |
--- a/runtime/bin/platform_win.cc |
+++ b/runtime/bin/platform_win.cc |
@@ -46,6 +46,7 @@ class PlatformWin { |
static void InitOnce() { |
platform_win_mutex_ = new Mutex(); |
saved_output_cp_ = -1; |
+ saved_input_cp_ = -1; |
// Set up a no-op handler so that CRT functions return an error instead of |
// hitting an assertion failure. |
// See: https://msdn.microsoft.com/en-us/library/a9yf33zb.aspx |
@@ -61,50 +62,89 @@ class PlatformWin { |
static void SaveAndConfigureConsole() { |
MutexLocker ml(platform_win_mutex_); |
+ // Set both the input and output code pages to UTF8. |
ASSERT(saved_output_cp_ == -1); |
+ ASSERT(saved_input_cp_ == -1); |
saved_output_cp_ = GetConsoleOutputCP(); |
+ saved_input_cp_ = GetConsoleCP(); |
SetConsoleOutputCP(CP_UTF8); |
+ SetConsoleCP(CP_UTF8); |
+ ansi_supported_ = true; |
HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE); |
- if ((out != INVALID_HANDLE_VALUE) && |
- GetConsoleMode(out, &saved_console_out_mode_)) { |
- const DWORD request = |
- saved_console_out_mode_ | ENABLE_VIRTUAL_TERMINAL_PROCESSING; |
- SetConsoleMode(out, request); |
+ DWORD out_mode; |
+ if ((out != INVALID_HANDLE_VALUE) && GetConsoleMode(out, &out_mode)) { |
+ const DWORD request = out_mode | ENABLE_VIRTUAL_TERMINAL_PROCESSING; |
+ ansi_supported_ = ansi_supported_ && SetConsoleMode(out, request); |
+ } else { |
+ ansi_supported_ = false; |
} |
HANDLE in = GetStdHandle(STD_INPUT_HANDLE); |
- if ((in != INVALID_HANDLE_VALUE) && |
- GetConsoleMode(in, &saved_console_in_mode_)) { |
- const DWORD request = |
- saved_console_in_mode_ | ENABLE_VIRTUAL_TERMINAL_INPUT; |
- SetConsoleMode(in, request); |
+ DWORD in_mode; |
+ if ((in != INVALID_HANDLE_VALUE) && GetConsoleMode(in, &in_mode)) { |
+ const DWORD request = in_mode | ENABLE_VIRTUAL_TERMINAL_INPUT; |
+ ansi_supported_ = ansi_supported_ && SetConsoleMode(in, request); |
+ } else { |
+ ansi_supported_ = false; |
sortie
2017/03/16 11:39:08
This looks like escape codes are considered unsupp
|
} |
} |
static void RestoreConsole() { |
MutexLocker ml(platform_win_mutex_); |
+ |
+ // STD_OUTPUT_HANDLE and STD_INPUT_HANDLE may have been closed or |
+ // redirected. Therefore, we explicitly open the CONOUT$ and CONIN$ |
+ // devices, so that we can be sure that we are really unsetting |
+ // ENABLE_VIRTUAL_TERMINAL_PROCESSING and ENABLE_VIRTUAL_TERMINAL_INPUT |
+ // respectively. |
+ HANDLE out; |
+ { |
+ Utf8ToWideScope conin("CONOUT$"); |
+ out = CreateFileW(conin.wide(), GENERIC_READ | GENERIC_WRITE, |
+ FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0); |
+ if (out != INVALID_HANDLE_VALUE) { |
+ SetStdHandle(STD_OUTPUT_HANDLE, out); |
+ } |
+ } |
+ DWORD out_mode; |
+ if ((out != INVALID_HANDLE_VALUE) && GetConsoleMode(out, &out_mode)) { |
+ DWORD request = out_mode & ~ENABLE_VIRTUAL_TERMINAL_INPUT; |
+ SetConsoleMode(out, request); |
+ } |
+ |
+ HANDLE in; |
+ { |
+ Utf8ToWideScope conin("CONIN$"); |
+ in = CreateFileW(conin.wide(), GENERIC_READ | GENERIC_WRITE, |
+ FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0); |
+ if (in != INVALID_HANDLE_VALUE) { |
+ SetStdHandle(STD_INPUT_HANDLE, in); |
+ } |
+ } |
+ DWORD in_mode; |
+ if ((in != INVALID_HANDLE_VALUE) && GetConsoleMode(in, &in_mode)) { |
+ DWORD request = in_mode & ~ENABLE_VIRTUAL_TERMINAL_INPUT; |
+ SetConsoleMode(in, request); |
+ } |
+ |
if (saved_output_cp_ != -1) { |
SetConsoleOutputCP(saved_output_cp_); |
saved_output_cp_ = -1; |
} |
- HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE); |
- if (out != INVALID_HANDLE_VALUE) { |
- SetConsoleMode(out, saved_console_out_mode_); |
- saved_console_out_mode_ = 0; |
- } |
- HANDLE in = GetStdHandle(STD_INPUT_HANDLE); |
- if (in != INVALID_HANDLE_VALUE) { |
- SetConsoleMode(in, saved_console_in_mode_); |
- saved_console_in_mode_ = 0; |
+ if (saved_input_cp_ != -1) { |
+ SetConsoleCP(saved_input_cp_); |
+ saved_input_cp_ = -1; |
} |
} |
+ static bool ansi_supported() { return ansi_supported_; } |
+ |
private: |
static Mutex* platform_win_mutex_; |
static int saved_output_cp_; |
- static DWORD saved_console_out_mode_; |
- static DWORD saved_console_in_mode_; |
+ static int saved_input_cp_; |
+ static bool ansi_supported_; |
static void InvalidParameterHandler(const wchar_t* expression, |
const wchar_t* function, |
@@ -120,9 +160,9 @@ class PlatformWin { |
}; |
int PlatformWin::saved_output_cp_ = -1; |
-DWORD PlatformWin::saved_console_out_mode_ = 0; |
-DWORD PlatformWin::saved_console_in_mode_ = 0; |
+int PlatformWin::saved_input_cp_ = -1; |
Mutex* PlatformWin::platform_win_mutex_ = NULL; |
+bool PlatformWin::ansi_supported_ = false; |
bool Platform::Initialize() { |
PlatformWin::InitOnce(); |
@@ -219,6 +259,11 @@ const char* Platform::ResolveExecutablePath() { |
} |
+bool Platform::AnsiSupported() { |
+ return PlatformWin::ansi_supported(); |
+} |
+ |
+ |
void Platform::Exit(int exit_code) { |
// TODO(zra): Remove once VM shuts down cleanly. |
::dart::private_flag_windows_run_tls_destructors = false; |