Index: runtime/bin/platform_win.cc |
diff --git a/runtime/bin/platform_win.cc b/runtime/bin/platform_win.cc |
index e34d515963d8bc9cf69a58c1e10f44c3d9b583a7..9f2f01c158d88db380af40b5d911a35ddb1f70d2 100644 |
--- a/runtime/bin/platform_win.cc |
+++ b/runtime/bin/platform_win.cc |
@@ -58,6 +58,19 @@ class PlatformWin { |
// the requested file. See: |
// See: https://msdn.microsoft.com/en-us/library/windows/desktop/ms680621(v=vs.85).aspx |
SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX); |
+ // Set up a signal handler that restores the console state on a |
+ // CTRL_C_EVENT signal. This will only run when there is no signal hanlder |
+ // registered for the CTRL_C_EVENT from Dart code. |
+ SetConsoleCtrlHandler(SignalHandler, TRUE); |
+ } |
+ |
+ static BOOL WINAPI SignalHandler(DWORD signal) { |
+ if (signal == CTRL_C_EVENT) { |
+ // We call this without taking the lock because this is a signal |
+ // handler, and because the process is about to go down. |
+ RestoreConsoleLocked(); |
+ } |
+ return FALSE; |
} |
static void SaveAndConfigureConsole() { |
@@ -92,20 +105,33 @@ class PlatformWin { |
static void RestoreConsole() { |
MutexLocker ml(platform_win_mutex_); |
+ RestoreConsoleLocked(); |
+ } |
+ |
+ static bool ansi_supported() { return ansi_supported_; } |
+ |
+ private: |
+ static Mutex* platform_win_mutex_; |
+ static int saved_output_cp_; |
+ static int saved_input_cp_; |
+ static bool ansi_supported_; |
+ static void RestoreConsoleLocked() { |
// 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); |
- } |
+ const intptr_t kWideBufLen = 64; |
+ const char* conout = "CONOUT$"; |
+ wchar_t widebuf[kWideBufLen]; |
+ int result = |
+ MultiByteToWideChar(CP_UTF8, 0, conout, -1, widebuf, kWideBufLen); |
+ ASSERT(result != 0); |
+ HANDLE out = CreateFileW(widebuf, 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)) { |
@@ -113,14 +139,13 @@ class PlatformWin { |
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); |
- } |
+ const char* conin = "CONIN$"; |
+ result = MultiByteToWideChar(CP_UTF8, 0, conin, -1, widebuf, kWideBufLen); |
+ ASSERT(result != 0); |
+ HANDLE in = CreateFileW(widebuf, 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)) { |
@@ -138,14 +163,6 @@ class PlatformWin { |
} |
} |
- static bool ansi_supported() { return ansi_supported_; } |
- |
- private: |
- static Mutex* platform_win_mutex_; |
- static int saved_output_cp_; |
- static int saved_input_cp_; |
- static bool ansi_supported_; |
- |
static void InvalidParameterHandler(const wchar_t* expression, |
const wchar_t* function, |
const wchar_t* file, |