Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(78)

Side by Side Diff: runtime/bin/platform_win.cc

Issue 2750833003: [dart:io][windows] Reset the console on ctrl-c (Closed)
Patch Set: Add the signal handler in PlatformWin Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "platform/globals.h" 5 #include "platform/globals.h"
6 #if defined(TARGET_OS_WINDOWS) 6 #if defined(TARGET_OS_WINDOWS)
7 7
8 #include "bin/platform.h" 8 #include "bin/platform.h"
9 9
10 #include <crtdbg.h> 10 #include <crtdbg.h>
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
51 // hitting an assertion failure. 51 // hitting an assertion failure.
52 // See: https://msdn.microsoft.com/en-us/library/a9yf33zb.aspx 52 // See: https://msdn.microsoft.com/en-us/library/a9yf33zb.aspx
53 _set_invalid_parameter_handler(InvalidParameterHandler); 53 _set_invalid_parameter_handler(InvalidParameterHandler);
54 // Disable the message box for assertions in the CRT in Debug builds. 54 // Disable the message box for assertions in the CRT in Debug builds.
55 // See: https://msdn.microsoft.com/en-us/library/1y71x448.aspx 55 // See: https://msdn.microsoft.com/en-us/library/1y71x448.aspx
56 _CrtSetReportMode(_CRT_ASSERT, 0); 56 _CrtSetReportMode(_CRT_ASSERT, 0);
57 // Disable dialog boxes for "critical" errors or when OpenFile cannot find 57 // Disable dialog boxes for "critical" errors or when OpenFile cannot find
58 // the requested file. See: 58 // the requested file. See:
59 // See: https://msdn.microsoft.com/en-us/library/windows/desktop/ms680621(v= vs.85).aspx 59 // See: https://msdn.microsoft.com/en-us/library/windows/desktop/ms680621(v= vs.85).aspx
60 SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX); 60 SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
61 // Set up a signal handler that restores the console state on a
62 // CTRL_C_EVENT signal. This will only run when there is no signal hanlder
63 // registered for the CTRL_C_EVENT from Dart code.
64 SetConsoleCtrlHandler(SignalHandler, TRUE);
65 }
66
67 static BOOL WINAPI SignalHandler(DWORD signal) {
68 if (signal == CTRL_C_EVENT) {
69 // We call this without taking the lock because this is a signal
70 // handler, and because the process is about to go down.
71 RestoreConsoleLocked();
72 }
73 return FALSE;
61 } 74 }
62 75
63 static void SaveAndConfigureConsole() { 76 static void SaveAndConfigureConsole() {
64 MutexLocker ml(platform_win_mutex_); 77 MutexLocker ml(platform_win_mutex_);
65 // Set both the input and output code pages to UTF8. 78 // Set both the input and output code pages to UTF8.
66 ASSERT(saved_output_cp_ == -1); 79 ASSERT(saved_output_cp_ == -1);
67 ASSERT(saved_input_cp_ == -1); 80 ASSERT(saved_input_cp_ == -1);
68 saved_output_cp_ = GetConsoleOutputCP(); 81 saved_output_cp_ = GetConsoleOutputCP();
69 saved_input_cp_ = GetConsoleCP(); 82 saved_input_cp_ = GetConsoleCP();
70 SetConsoleOutputCP(CP_UTF8); 83 SetConsoleOutputCP(CP_UTF8);
(...skipping 14 matching lines...) Expand all
85 if ((in != INVALID_HANDLE_VALUE) && GetConsoleMode(in, &in_mode)) { 98 if ((in != INVALID_HANDLE_VALUE) && GetConsoleMode(in, &in_mode)) {
86 const DWORD request = in_mode | ENABLE_VIRTUAL_TERMINAL_INPUT; 99 const DWORD request = in_mode | ENABLE_VIRTUAL_TERMINAL_INPUT;
87 ansi_supported_ = ansi_supported_ && SetConsoleMode(in, request); 100 ansi_supported_ = ansi_supported_ && SetConsoleMode(in, request);
88 } else { 101 } else {
89 ansi_supported_ = false; 102 ansi_supported_ = false;
90 } 103 }
91 } 104 }
92 105
93 static void RestoreConsole() { 106 static void RestoreConsole() {
94 MutexLocker ml(platform_win_mutex_); 107 MutexLocker ml(platform_win_mutex_);
108 RestoreConsoleLocked();
109 }
95 110
111 static bool ansi_supported() { return ansi_supported_; }
112
113 private:
114 static Mutex* platform_win_mutex_;
115 static int saved_output_cp_;
116 static int saved_input_cp_;
117 static bool ansi_supported_;
118
119 static void RestoreConsoleLocked() {
96 // STD_OUTPUT_HANDLE and STD_INPUT_HANDLE may have been closed or 120 // STD_OUTPUT_HANDLE and STD_INPUT_HANDLE may have been closed or
97 // redirected. Therefore, we explicitly open the CONOUT$ and CONIN$ 121 // redirected. Therefore, we explicitly open the CONOUT$ and CONIN$
98 // devices, so that we can be sure that we are really unsetting 122 // devices, so that we can be sure that we are really unsetting
99 // ENABLE_VIRTUAL_TERMINAL_PROCESSING and ENABLE_VIRTUAL_TERMINAL_INPUT 123 // ENABLE_VIRTUAL_TERMINAL_PROCESSING and ENABLE_VIRTUAL_TERMINAL_INPUT
100 // respectively. 124 // respectively.
101 HANDLE out; 125 const intptr_t kWideBufLen = 64;
102 { 126 const char* conout = "CONOUT$";
103 Utf8ToWideScope conin("CONOUT$"); 127 wchar_t widebuf[kWideBufLen];
104 out = CreateFileW(conin.wide(), GENERIC_READ | GENERIC_WRITE, 128 int result =
105 FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0); 129 MultiByteToWideChar(CP_UTF8, 0, conout, -1, widebuf, kWideBufLen);
106 if (out != INVALID_HANDLE_VALUE) { 130 ASSERT(result != 0);
107 SetStdHandle(STD_OUTPUT_HANDLE, out); 131 HANDLE out = CreateFileW(widebuf, GENERIC_READ | GENERIC_WRITE,
108 } 132 FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
133 if (out != INVALID_HANDLE_VALUE) {
134 SetStdHandle(STD_OUTPUT_HANDLE, out);
109 } 135 }
110 DWORD out_mode; 136 DWORD out_mode;
111 if ((out != INVALID_HANDLE_VALUE) && GetConsoleMode(out, &out_mode)) { 137 if ((out != INVALID_HANDLE_VALUE) && GetConsoleMode(out, &out_mode)) {
112 DWORD request = out_mode & ~ENABLE_VIRTUAL_TERMINAL_INPUT; 138 DWORD request = out_mode & ~ENABLE_VIRTUAL_TERMINAL_INPUT;
113 SetConsoleMode(out, request); 139 SetConsoleMode(out, request);
114 } 140 }
115 141
116 HANDLE in; 142 const char* conin = "CONIN$";
117 { 143 result = MultiByteToWideChar(CP_UTF8, 0, conin, -1, widebuf, kWideBufLen);
118 Utf8ToWideScope conin("CONIN$"); 144 ASSERT(result != 0);
119 in = CreateFileW(conin.wide(), GENERIC_READ | GENERIC_WRITE, 145 HANDLE in = CreateFileW(widebuf, GENERIC_READ | GENERIC_WRITE,
120 FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0); 146 FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
121 if (in != INVALID_HANDLE_VALUE) { 147 if (in != INVALID_HANDLE_VALUE) {
122 SetStdHandle(STD_INPUT_HANDLE, in); 148 SetStdHandle(STD_INPUT_HANDLE, in);
123 }
124 } 149 }
125 DWORD in_mode; 150 DWORD in_mode;
126 if ((in != INVALID_HANDLE_VALUE) && GetConsoleMode(in, &in_mode)) { 151 if ((in != INVALID_HANDLE_VALUE) && GetConsoleMode(in, &in_mode)) {
127 DWORD request = in_mode & ~ENABLE_VIRTUAL_TERMINAL_INPUT; 152 DWORD request = in_mode & ~ENABLE_VIRTUAL_TERMINAL_INPUT;
128 SetConsoleMode(in, request); 153 SetConsoleMode(in, request);
129 } 154 }
130 155
131 if (saved_output_cp_ != -1) { 156 if (saved_output_cp_ != -1) {
132 SetConsoleOutputCP(saved_output_cp_); 157 SetConsoleOutputCP(saved_output_cp_);
133 saved_output_cp_ = -1; 158 saved_output_cp_ = -1;
134 } 159 }
135 if (saved_input_cp_ != -1) { 160 if (saved_input_cp_ != -1) {
136 SetConsoleCP(saved_input_cp_); 161 SetConsoleCP(saved_input_cp_);
137 saved_input_cp_ = -1; 162 saved_input_cp_ = -1;
138 } 163 }
139 } 164 }
140 165
141 static bool ansi_supported() { return ansi_supported_; }
142
143 private:
144 static Mutex* platform_win_mutex_;
145 static int saved_output_cp_;
146 static int saved_input_cp_;
147 static bool ansi_supported_;
148
149 static void InvalidParameterHandler(const wchar_t* expression, 166 static void InvalidParameterHandler(const wchar_t* expression,
150 const wchar_t* function, 167 const wchar_t* function,
151 const wchar_t* file, 168 const wchar_t* file,
152 unsigned int line, 169 unsigned int line,
153 uintptr_t reserved) { 170 uintptr_t reserved) {
154 // Doing nothing here means that the CRT call that invoked it will 171 // Doing nothing here means that the CRT call that invoked it will
155 // return an error code and/or set errno. 172 // return an error code and/or set errno.
156 } 173 }
157 174
158 DISALLOW_ALLOCATION(); 175 DISALLOW_ALLOCATION();
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
271 PlatformWin::RestoreConsole(); 288 PlatformWin::RestoreConsole();
272 // On Windows we use ExitProcess so that threads can't clobber the exit_code. 289 // On Windows we use ExitProcess so that threads can't clobber the exit_code.
273 // See: https://code.google.com/p/nativeclient/issues/detail?id=2870 290 // See: https://code.google.com/p/nativeclient/issues/detail?id=2870
274 ::ExitProcess(exit_code); 291 ::ExitProcess(exit_code);
275 } 292 }
276 293
277 } // namespace bin 294 } // namespace bin
278 } // namespace dart 295 } // namespace dart
279 296
280 #endif // defined(TARGET_OS_WINDOWS) 297 #endif // defined(TARGET_OS_WINDOWS)
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698