[VM] Refactored console configuration out of platform_*.cc into console_config.h and reapplied c9700040c3 for POSIX platforms (Windows needs more work). We may also want to move code in bin/stdio.h.
Change-Id: Ic7cbc690f490e0127387d9a23866ea7eddbc84cf Reviewed-on: https://dart-review.googlesource.com/45746 Commit-Queue: Ben Konyi <bkonyi@google.com> Reviewed-by: Zach Anderson <zra@google.com>
This commit is contained in:
committed by
commit-bot@chromium.org
parent
180866dc46
commit
3c8d3b6870
@@ -0,0 +1,26 @@
|
||||
// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
#ifndef RUNTIME_BIN_CONSOLE_H_
|
||||
#define RUNTIME_BIN_CONSOLE_H_
|
||||
|
||||
#include "platform/globals.h"
|
||||
|
||||
namespace dart {
|
||||
namespace bin {
|
||||
|
||||
class Console {
|
||||
public:
|
||||
static void SaveConfig();
|
||||
static void RestoreConfig();
|
||||
|
||||
private:
|
||||
DISALLOW_ALLOCATION();
|
||||
DISALLOW_IMPLICIT_CONSTRUCTORS(Console);
|
||||
};
|
||||
|
||||
} // namespace bin
|
||||
} // namespace dart
|
||||
|
||||
#endif // RUNTIME_BIN_CONSOLE_H_
|
||||
@@ -0,0 +1,92 @@
|
||||
// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
#include "platform/globals.h"
|
||||
#if defined(HOST_OS_LINUX) || defined(HOST_OS_MACOS) || \
|
||||
defined(HOST_OS_ANDROID) || defined(HOST_OS_FUCHSIA)
|
||||
|
||||
#include "bin/console.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <termios.h>
|
||||
|
||||
#include "bin/fdutils.h"
|
||||
#include "platform/signal_blocker.h"
|
||||
|
||||
namespace dart {
|
||||
namespace bin {
|
||||
|
||||
class PosixConsole {
|
||||
public:
|
||||
static const tcflag_t kInvalidFlag = -1;
|
||||
|
||||
static void Initialize() {
|
||||
SaveMode(STDOUT_FILENO, &stdout_initial_c_lflag_);
|
||||
SaveMode(STDERR_FILENO, &stderr_initial_c_lflag_);
|
||||
SaveMode(STDIN_FILENO, &stdin_initial_c_lflag_);
|
||||
}
|
||||
|
||||
static void Cleanup() {
|
||||
RestoreMode(STDOUT_FILENO, stdout_initial_c_lflag_);
|
||||
RestoreMode(STDERR_FILENO, stderr_initial_c_lflag_);
|
||||
RestoreMode(STDIN_FILENO, stdin_initial_c_lflag_);
|
||||
ClearLFlags();
|
||||
}
|
||||
|
||||
private:
|
||||
static tcflag_t stdout_initial_c_lflag_;
|
||||
static tcflag_t stderr_initial_c_lflag_;
|
||||
static tcflag_t stdin_initial_c_lflag_;
|
||||
|
||||
static void ClearLFlags() {
|
||||
stdout_initial_c_lflag_ = kInvalidFlag;
|
||||
stderr_initial_c_lflag_ = kInvalidFlag;
|
||||
stdin_initial_c_lflag_ = kInvalidFlag;
|
||||
}
|
||||
|
||||
static void SaveMode(intptr_t fd, tcflag_t* flag) {
|
||||
ASSERT(flag != NULL);
|
||||
struct termios term;
|
||||
int status = NO_RETRY_EXPECTED(tcgetattr(fd, &term));
|
||||
if (status != 0) {
|
||||
return;
|
||||
}
|
||||
*flag = term.c_lflag;
|
||||
}
|
||||
|
||||
static void RestoreMode(intptr_t fd, tcflag_t flag) {
|
||||
if (flag == kInvalidFlag) {
|
||||
return;
|
||||
}
|
||||
struct termios term;
|
||||
int status = NO_RETRY_EXPECTED(tcgetattr(fd, &term));
|
||||
if (status != 0) {
|
||||
return;
|
||||
}
|
||||
term.c_lflag = flag;
|
||||
NO_RETRY_EXPECTED(tcsetattr(fd, TCSANOW, &term));
|
||||
}
|
||||
|
||||
DISALLOW_ALLOCATION();
|
||||
DISALLOW_IMPLICIT_CONSTRUCTORS(PosixConsole);
|
||||
};
|
||||
|
||||
tcflag_t PosixConsole::stdout_initial_c_lflag_ = PosixConsole::kInvalidFlag;
|
||||
tcflag_t PosixConsole::stderr_initial_c_lflag_ = PosixConsole::kInvalidFlag;
|
||||
tcflag_t PosixConsole::stdin_initial_c_lflag_ = PosixConsole::kInvalidFlag;
|
||||
|
||||
void Console::SaveConfig() {
|
||||
PosixConsole::Initialize();
|
||||
}
|
||||
|
||||
void Console::RestoreConfig() {
|
||||
PosixConsole::Cleanup();
|
||||
}
|
||||
|
||||
} // namespace bin
|
||||
} // namespace dart
|
||||
|
||||
#endif // defined(HOST_OS_LINUX) || defined(HOST_OS_MACOS) || \
|
||||
// defined(HOST_OS_ANDROID) || defined(HOST_OS_FUCHSIA)
|
||||
@@ -0,0 +1,143 @@
|
||||
// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
#include "platform/globals.h"
|
||||
#if defined(HOST_OS_WINDOWS)
|
||||
#include "bin/console.h"
|
||||
|
||||
#include "bin/file.h"
|
||||
#include "bin/lockers.h"
|
||||
#include "bin/platform.h"
|
||||
#include "bin/utils.h"
|
||||
#include "bin/utils_win.h"
|
||||
|
||||
// These are not always defined in the header files. See:
|
||||
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms686033(v=vs.85).aspx
|
||||
#ifndef ENABLE_VIRTUAL_TERMINAL_INPUT
|
||||
#define ENABLE_VIRTUAL_TERMINAL_INPUT 0x0200
|
||||
#endif
|
||||
|
||||
#ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING
|
||||
#define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004
|
||||
#endif
|
||||
|
||||
namespace dart {
|
||||
namespace bin {
|
||||
|
||||
class ConsoleWin {
|
||||
public:
|
||||
static const int kInvalidFlag = -1;
|
||||
|
||||
static void Initialize() {
|
||||
saved_output_cp_ = kInvalidFlag;
|
||||
saved_input_cp_ = kInvalidFlag;
|
||||
// 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 handler
|
||||
// registered for the CTRL_C_EVENT from Dart code.
|
||||
SetConsoleCtrlHandler(SignalHandler, TRUE);
|
||||
|
||||
// Set both the input and output code pages to UTF8.
|
||||
const int output_cp = GetConsoleOutputCP();
|
||||
const int input_cp = GetConsoleCP();
|
||||
if (output_cp != CP_UTF8) {
|
||||
SetConsoleOutputCP(CP_UTF8);
|
||||
saved_output_cp_ = output_cp;
|
||||
}
|
||||
if (input_cp != CP_UTF8) {
|
||||
SetConsoleCP(CP_UTF8);
|
||||
saved_input_cp_ = input_cp;
|
||||
}
|
||||
|
||||
// Try to set the bits for ANSI support, but swallow any failures.
|
||||
saved_stdout_mode_ =
|
||||
ModifyMode(STD_OUTPUT_HANDLE, ENABLE_VIRTUAL_TERMINAL_PROCESSING);
|
||||
|
||||
// TODO(28984): Due to issue #29104, we cannot set
|
||||
// ENABLE_VIRTUAL_TERMINAL_INPUT here, as it causes ENABLE_PROCESSED_INPUT
|
||||
// to be ignored.
|
||||
}
|
||||
|
||||
static void Cleanup() {
|
||||
// STD_OUTPUT_HANDLE, may have been closed or redirected. Therefore, we
|
||||
// explicitly open the CONOUT$, CONERR$ and CONIN$ devices, so that we can
|
||||
// be sure that we are really restoring the console to its original state.
|
||||
if (saved_stdout_mode_ != kInvalidFlag) {
|
||||
CleanupDevices("CONOUT$", STD_OUTPUT_HANDLE, saved_stdout_mode_);
|
||||
saved_stdout_mode_ = kInvalidFlag;
|
||||
}
|
||||
if (saved_output_cp_ != kInvalidFlag) {
|
||||
SetConsoleOutputCP(saved_output_cp_);
|
||||
saved_output_cp_ = kInvalidFlag;
|
||||
}
|
||||
if (saved_input_cp_ != kInvalidFlag) {
|
||||
SetConsoleCP(saved_input_cp_);
|
||||
saved_input_cp_ = kInvalidFlag;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
static int saved_output_cp_;
|
||||
static int saved_input_cp_;
|
||||
static DWORD saved_stdout_mode_;
|
||||
|
||||
static BOOL WINAPI SignalHandler(DWORD signal) {
|
||||
if (signal == CTRL_C_EVENT) {
|
||||
Cleanup();
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static DWORD ModifyMode(DWORD handle, DWORD flags) {
|
||||
HANDLE h = GetStdHandle(handle);
|
||||
DWORD mode;
|
||||
DWORD old_mode = 0;
|
||||
|
||||
if ((h != INVALID_HANDLE_VALUE) && GetConsoleMode(h, &mode)) {
|
||||
old_mode = mode;
|
||||
if (flags != 0) {
|
||||
const DWORD request = mode | flags;
|
||||
SetConsoleMode(h, request);
|
||||
}
|
||||
}
|
||||
return old_mode;
|
||||
}
|
||||
|
||||
static void CleanupDevices(const char* device,
|
||||
DWORD handle,
|
||||
DWORD orig_flags) {
|
||||
const intptr_t kWideBufLen = 64;
|
||||
wchar_t widebuf[kWideBufLen];
|
||||
int result =
|
||||
MultiByteToWideChar(CP_UTF8, 0, device, -1, widebuf, kWideBufLen);
|
||||
ASSERT(result != 0);
|
||||
HANDLE h = CreateFileW(widebuf, GENERIC_READ | GENERIC_WRITE,
|
||||
FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
|
||||
if (h != INVALID_HANDLE_VALUE) {
|
||||
SetStdHandle(STD_OUTPUT_HANDLE, h);
|
||||
if (orig_flags != kInvalidFlag) {
|
||||
SetConsoleMode(h, orig_flags);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DISALLOW_ALLOCATION();
|
||||
DISALLOW_IMPLICIT_CONSTRUCTORS(ConsoleWin);
|
||||
};
|
||||
|
||||
int ConsoleWin::saved_output_cp_ = ConsoleWin::kInvalidFlag;
|
||||
int ConsoleWin::saved_input_cp_ = ConsoleWin::kInvalidFlag;
|
||||
DWORD ConsoleWin::saved_stdout_mode_ = ConsoleWin::kInvalidFlag;
|
||||
|
||||
void Console::SaveConfig() {
|
||||
ConsoleWin::Initialize();
|
||||
}
|
||||
|
||||
void Console::RestoreConfig() {
|
||||
ConsoleWin::Cleanup();
|
||||
}
|
||||
|
||||
} // namespace bin
|
||||
} // namespace dart
|
||||
|
||||
#endif // defined(HOST_OS_WINDOWS)
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <cstdarg>
|
||||
|
||||
#include "bin/builtin.h"
|
||||
#include "bin/console.h"
|
||||
#include "bin/dartutils.h"
|
||||
#include "bin/dfe.h"
|
||||
#include "bin/eventhandler.h"
|
||||
@@ -1489,6 +1490,7 @@ int main(int argc, char** argv) {
|
||||
Log::PrintErr("Initialization failed\n");
|
||||
return kErrorExitCode;
|
||||
}
|
||||
Console::SaveConfig();
|
||||
Thread::InitOnce();
|
||||
Loader::InitOnce();
|
||||
DartUtils::SetOriginalWorkingDirectory();
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
# This file contains some C++ sources for the dart:io library. The other
|
||||
# implementation files are in builtin_impl_sources.gypi.
|
||||
io_impl_sources = [
|
||||
"console.h",
|
||||
"console_posix.cc",
|
||||
"console_win.cc",
|
||||
"eventhandler.cc",
|
||||
"eventhandler.h",
|
||||
"eventhandler_android.cc",
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "include/dart_tools_api.h"
|
||||
|
||||
#include "bin/builtin.h"
|
||||
#include "bin/console.h"
|
||||
#include "bin/dartutils.h"
|
||||
#include "bin/dfe.h"
|
||||
#include "bin/directory.h"
|
||||
@@ -1008,6 +1009,9 @@ void main(int argc, char** argv) {
|
||||
Platform::Exit(kErrorExitCode);
|
||||
}
|
||||
|
||||
// Save the console state so we can restore it at shutdown.
|
||||
Console::SaveConfig();
|
||||
|
||||
// On Windows, the argv strings are code page encoded and not
|
||||
// utf8. We need to convert them to utf8.
|
||||
bool argv_converted = ShellUtils::GetUtf8Argv(argc, argv);
|
||||
|
||||
@@ -7,14 +7,14 @@
|
||||
|
||||
#include "bin/platform.h"
|
||||
|
||||
#include <errno.h> // NOLINT
|
||||
#include <signal.h> // NOLINT
|
||||
#include <string.h> // NOLINT
|
||||
#include <sys/utsname.h> // NOLINT
|
||||
#include <unistd.h> // NOLINT
|
||||
|
||||
#include "bin/fdutils.h"
|
||||
#include "bin/console.h"
|
||||
#include "bin/file.h"
|
||||
#include "bin/log.h"
|
||||
|
||||
namespace dart {
|
||||
namespace bin {
|
||||
@@ -152,6 +152,7 @@ const char* Platform::ResolveExecutablePath() {
|
||||
}
|
||||
|
||||
void Platform::Exit(int exit_code) {
|
||||
Console::RestoreConfig();
|
||||
exit(exit_code);
|
||||
}
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <zircon/status.h>
|
||||
#include <zircon/syscalls.h>
|
||||
|
||||
#include "bin/console.h"
|
||||
#include "bin/dartutils.h"
|
||||
#include "bin/fdutils.h"
|
||||
#include "bin/file.h"
|
||||
@@ -147,6 +148,7 @@ const char* Platform::ResolveExecutablePath() {
|
||||
}
|
||||
|
||||
void Platform::Exit(int exit_code) {
|
||||
Console::RestoreConfig();
|
||||
exit(exit_code);
|
||||
}
|
||||
|
||||
|
||||
@@ -7,14 +7,14 @@
|
||||
|
||||
#include "bin/platform.h"
|
||||
|
||||
#include <errno.h> // NOLINT
|
||||
#include <signal.h> // NOLINT
|
||||
#include <string.h> // NOLINT
|
||||
#include <sys/utsname.h> // NOLINT
|
||||
#include <unistd.h> // NOLINT
|
||||
|
||||
#include "bin/fdutils.h"
|
||||
#include "bin/console.h"
|
||||
#include "bin/file.h"
|
||||
#include "bin/log.h"
|
||||
|
||||
namespace dart {
|
||||
namespace bin {
|
||||
@@ -152,6 +152,7 @@ const char* Platform::ResolveExecutablePath() {
|
||||
}
|
||||
|
||||
void Platform::Exit(int exit_code) {
|
||||
Console::RestoreConfig();
|
||||
exit(exit_code);
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#if !HOST_OS_IOS
|
||||
#include <crt_externs.h> // NOLINT
|
||||
#endif // !HOST_OS_IOS
|
||||
#include <errno.h> // NOLINT
|
||||
#include <mach-o/dyld.h>
|
||||
#include <signal.h> // NOLINT
|
||||
#include <string.h> // NOLINT
|
||||
@@ -20,9 +21,8 @@
|
||||
#include <sys/utsname.h> // NOLINT
|
||||
#include <unistd.h> // NOLINT
|
||||
|
||||
#include "bin/fdutils.h"
|
||||
#include "bin/console.h"
|
||||
#include "bin/file.h"
|
||||
#include "bin/log.h"
|
||||
|
||||
namespace dart {
|
||||
namespace bin {
|
||||
@@ -240,6 +240,7 @@ const char* Platform::ResolveExecutablePath() {
|
||||
}
|
||||
|
||||
void Platform::Exit(int exit_code) {
|
||||
Console::RestoreConfig();
|
||||
exit(exit_code);
|
||||
}
|
||||
|
||||
|
||||
+2
-115
@@ -9,6 +9,7 @@
|
||||
|
||||
#include <crtdbg.h>
|
||||
|
||||
#include "bin/console.h"
|
||||
#include "bin/file.h"
|
||||
#include "bin/lockers.h"
|
||||
#include "bin/log.h"
|
||||
@@ -19,15 +20,6 @@
|
||||
#include "bin/utils.h"
|
||||
#include "bin/utils_win.h"
|
||||
|
||||
// These are not always defined in the header files. See:
|
||||
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms686033(v=vs.85).aspx
|
||||
#ifndef ENABLE_VIRTUAL_TERMINAL_INPUT
|
||||
#define ENABLE_VIRTUAL_TERMINAL_INPUT 0x0200
|
||||
#endif
|
||||
|
||||
#ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING
|
||||
#define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004
|
||||
#endif
|
||||
|
||||
namespace dart {
|
||||
|
||||
@@ -44,9 +36,6 @@ char** Platform::argv_ = NULL;
|
||||
class PlatformWin {
|
||||
public:
|
||||
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
|
||||
@@ -59,58 +48,12 @@ class PlatformWin {
|
||||
// See: https://msdn.microsoft.com/en-us/library/windows/desktop/ms680621(v=vs.85).aspx
|
||||
SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX |
|
||||
SEM_NOGPFAULTERRORBOX);
|
||||
// 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 handler
|
||||
// registered for the CTRL_C_EVENT from Dart code.
|
||||
SetConsoleCtrlHandler(SignalHandler, TRUE);
|
||||
#ifndef PRODUCT
|
||||
// Set up global exception handler to be able to dump stack trace on crash.
|
||||
SetExceptionHandler();
|
||||
#endif
|
||||
}
|
||||
|
||||
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() {
|
||||
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);
|
||||
const int output_cp = GetConsoleOutputCP();
|
||||
const int input_cp = GetConsoleCP();
|
||||
if (output_cp != CP_UTF8) {
|
||||
SetConsoleOutputCP(CP_UTF8);
|
||||
saved_output_cp_ = output_cp;
|
||||
}
|
||||
if (input_cp != CP_UTF8) {
|
||||
SetConsoleCP(CP_UTF8);
|
||||
saved_input_cp_ = input_cp;
|
||||
}
|
||||
|
||||
// Try to set the bits for ANSI support, but swallow any failures.
|
||||
HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
DWORD out_mode;
|
||||
if ((out != INVALID_HANDLE_VALUE) && GetConsoleMode(out, &out_mode)) {
|
||||
const DWORD request = out_mode | ENABLE_VIRTUAL_TERMINAL_PROCESSING;
|
||||
SetConsoleMode(out, request);
|
||||
}
|
||||
// TODO(28984): Due to issue #29104, we cannot set
|
||||
// ENABLE_VIRTUAL_TERMINAL_INPUT here, as it causes ENABLE_PROCESSED_INPUT
|
||||
// to be ignored.
|
||||
}
|
||||
|
||||
static void RestoreConsole() {
|
||||
MutexLocker ml(platform_win_mutex_);
|
||||
RestoreConsoleLocked();
|
||||
}
|
||||
|
||||
// Windows top-level unhandled exception handler function.
|
||||
// See MSDN documentation for UnhandledExceptionFilter.
|
||||
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms681401(v=vs.85).aspx
|
||||
@@ -139,57 +82,6 @@ class PlatformWin {
|
||||
}
|
||||
|
||||
private:
|
||||
static Mutex* platform_win_mutex_;
|
||||
static int saved_output_cp_;
|
||||
static int saved_input_cp_;
|
||||
|
||||
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.
|
||||
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)) {
|
||||
DWORD request = out_mode & ~ENABLE_VIRTUAL_TERMINAL_INPUT;
|
||||
SetConsoleMode(out, request);
|
||||
}
|
||||
|
||||
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)) {
|
||||
DWORD request = in_mode & ~ENABLE_VIRTUAL_TERMINAL_INPUT;
|
||||
SetConsoleMode(in, request);
|
||||
}
|
||||
|
||||
if (saved_output_cp_ != -1) {
|
||||
SetConsoleOutputCP(saved_output_cp_);
|
||||
saved_output_cp_ = -1;
|
||||
}
|
||||
if (saved_input_cp_ != -1) {
|
||||
SetConsoleCP(saved_input_cp_);
|
||||
saved_input_cp_ = -1;
|
||||
}
|
||||
}
|
||||
|
||||
static void InvalidParameterHandler(const wchar_t* expression,
|
||||
const wchar_t* function,
|
||||
const wchar_t* file,
|
||||
@@ -203,13 +95,8 @@ class PlatformWin {
|
||||
DISALLOW_IMPLICIT_CONSTRUCTORS(PlatformWin);
|
||||
};
|
||||
|
||||
int PlatformWin::saved_output_cp_ = -1;
|
||||
int PlatformWin::saved_input_cp_ = -1;
|
||||
Mutex* PlatformWin::platform_win_mutex_ = NULL;
|
||||
|
||||
bool Platform::Initialize() {
|
||||
PlatformWin::InitOnce();
|
||||
PlatformWin::SaveAndConfigureConsole();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -394,7 +281,7 @@ void Platform::Exit(int exit_code) {
|
||||
// TODO(zra): Remove once VM shuts down cleanly.
|
||||
::dart::private_flag_windows_run_tls_destructors = false;
|
||||
// Restore the console's output code page
|
||||
PlatformWin::RestoreConsole();
|
||||
Console::RestoreConfig();
|
||||
// On Windows we use ExitProcess so that threads can't clobber the exit_code.
|
||||
// See: https://code.google.com/p/nativeclient/issues/detail?id=2870
|
||||
::ExitProcess(exit_code);
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "bin/console.h"
|
||||
#include "bin/dartutils.h"
|
||||
#include "bin/dfe.h"
|
||||
#include "bin/eventhandler.h"
|
||||
@@ -212,6 +213,9 @@ static int Main(int argc, const char** argv) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Save the console state so we can restore it later.
|
||||
dart::bin::Console::SaveConfig();
|
||||
|
||||
if (argc < 2) {
|
||||
// Bad parameter count.
|
||||
PrintUsage();
|
||||
|
||||
Reference in New Issue
Block a user