1// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
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.
4
5#include "platform/globals.h"
6#if defined(HOST_OS_LINUX) || defined(HOST_OS_MACOS) || \
7 defined(HOST_OS_ANDROID) || defined(HOST_OS_FUCHSIA)
8
9#include "bin/console.h"
10
11#include <errno.h>
12#include <sys/ioctl.h>
13#include <termios.h>
14
15#include "bin/fdutils.h"
16#include "platform/signal_blocker.h"
17
18namespace dart {
19namespace bin {
20
21class PosixConsole {
22 public:
23 static const tcflag_t kInvalidFlag = -1;
24
25 static void Initialize() {
26 SaveMode(STDOUT_FILENO, &stdout_initial_c_lflag_);
27 SaveMode(STDERR_FILENO, &stderr_initial_c_lflag_);
28 SaveMode(STDIN_FILENO, &stdin_initial_c_lflag_);
29 }
30
31 static void Cleanup() {
32 RestoreMode(STDOUT_FILENO, stdout_initial_c_lflag_);
33 RestoreMode(STDERR_FILENO, stderr_initial_c_lflag_);
34 RestoreMode(STDIN_FILENO, stdin_initial_c_lflag_);
35 ClearLFlags();
36 }
37
38 private:
39 static tcflag_t stdout_initial_c_lflag_;
40 static tcflag_t stderr_initial_c_lflag_;
41 static tcflag_t stdin_initial_c_lflag_;
42
43 static void ClearLFlags() {
44 stdout_initial_c_lflag_ = kInvalidFlag;
45 stderr_initial_c_lflag_ = kInvalidFlag;
46 stdin_initial_c_lflag_ = kInvalidFlag;
47 }
48
49 static void SaveMode(intptr_t fd, tcflag_t* flag) {
50 ASSERT(flag != NULL);
51 struct termios term;
52 int status = TEMP_FAILURE_RETRY(tcgetattr(fd, &term));
53 if (status != 0) {
54 return;
55 }
56 *flag = term.c_lflag;
57 }
58
59 static void RestoreMode(intptr_t fd, tcflag_t flag) {
60 if (flag == kInvalidFlag) {
61 return;
62 }
63 struct termios term;
64 int status = TEMP_FAILURE_RETRY(tcgetattr(fd, &term));
65 if (status != 0) {
66 return;
67 }
68 term.c_lflag = flag;
69 VOID_TEMP_FAILURE_RETRY(tcsetattr(fd, TCSANOW, &term));
70 }
71
72 DISALLOW_ALLOCATION();
73 DISALLOW_IMPLICIT_CONSTRUCTORS(PosixConsole);
74};
75
76tcflag_t PosixConsole::stdout_initial_c_lflag_ = PosixConsole::kInvalidFlag;
77tcflag_t PosixConsole::stderr_initial_c_lflag_ = PosixConsole::kInvalidFlag;
78tcflag_t PosixConsole::stdin_initial_c_lflag_ = PosixConsole::kInvalidFlag;
79
80void Console::SaveConfig() {
81 PosixConsole::Initialize();
82}
83
84void Console::RestoreConfig() {
85 PosixConsole::Cleanup();
86}
87
88} // namespace bin
89} // namespace dart
90
91#endif // defined(HOST_OS_LINUX) || defined(HOST_OS_MACOS) ||
92 // defined(HOST_OS_ANDROID) || defined(HOST_OS_FUCHSIA)
93