1 | //===-- Terminal.h ----------------------------------------------*- C++ -*-===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #ifndef LLDB_HOST_TERMINAL_H |
10 | #define LLDB_HOST_TERMINAL_H |
11 | |
12 | #include "lldb/lldb-private.h" |
13 | #include "llvm/Support/Error.h" |
14 | |
15 | namespace lldb_private { |
16 | |
17 | class TerminalState; |
18 | |
19 | class Terminal { |
20 | public: |
21 | enum class Parity { |
22 | No, |
23 | Even, |
24 | Odd, |
25 | Space, |
26 | Mark, |
27 | }; |
28 | |
29 | enum class ParityCheck { |
30 | // No parity checking |
31 | No, |
32 | // Replace erraneous bytes with NUL |
33 | ReplaceWithNUL, |
34 | // Ignore erraneous bytes |
35 | Ignore, |
36 | // Mark erraneous bytes by prepending them with \xFF\x00; real \xFF |
37 | // is escaped to \xFF\xFF |
38 | Mark, |
39 | }; |
40 | |
41 | Terminal(int fd = -1) : m_fd(fd) {} |
42 | |
43 | ~Terminal() = default; |
44 | |
45 | bool IsATerminal() const; |
46 | |
47 | int GetFileDescriptor() const { return m_fd; } |
48 | |
49 | void SetFileDescriptor(int fd) { m_fd = fd; } |
50 | |
51 | bool FileDescriptorIsValid() const { return m_fd != -1; } |
52 | |
53 | void Clear() { m_fd = -1; } |
54 | |
55 | llvm::Error SetEcho(bool enabled); |
56 | |
57 | llvm::Error SetCanonical(bool enabled); |
58 | |
59 | llvm::Error SetRaw(); |
60 | |
61 | llvm::Error SetBaudRate(unsigned int baud_rate); |
62 | |
63 | llvm::Error SetStopBits(unsigned int stop_bits); |
64 | |
65 | llvm::Error SetParity(Parity parity); |
66 | |
67 | llvm::Error SetParityCheck(ParityCheck parity_check); |
68 | |
69 | llvm::Error SetHardwareFlowControl(bool enabled); |
70 | |
71 | protected: |
72 | struct Data; |
73 | |
74 | int m_fd; // This may or may not be a terminal file descriptor |
75 | |
76 | llvm::Expected<Data> GetData(); |
77 | llvm::Error SetData(const Data &data); |
78 | |
79 | friend class TerminalState; |
80 | }; |
81 | |
82 | /// \class TerminalState Terminal.h "lldb/Host/Terminal.h" |
83 | /// A RAII-friendly terminal state saving/restoring class. |
84 | /// |
85 | /// This class can be used to remember the terminal state for a file |
86 | /// descriptor and later restore that state as it originally was. |
87 | class TerminalState { |
88 | public: |
89 | /// Construct a new instance and optionally save terminal state. |
90 | /// |
91 | /// \param[in] term |
92 | /// The Terminal instance holding the file descriptor to save the state |
93 | /// of. If the instance is not associated with a fd, no state will |
94 | /// be saved. |
95 | /// |
96 | /// \param[in] save_process_group |
97 | /// If \b true, save the process group settings, else do not |
98 | /// save the process group settings for a TTY. |
99 | TerminalState(Terminal term = -1, bool save_process_group = false); |
100 | |
101 | /// Destroy the instance, restoring terminal state if saved. If restoring |
102 | /// state is undesirable, the instance needs to be reset before destruction. |
103 | ~TerminalState(); |
104 | |
105 | /// Save the TTY state for \a fd. |
106 | /// |
107 | /// Save the current state of the TTY for the file descriptor "fd" and if |
108 | /// "save_process_group" is true, attempt to save the process group info for |
109 | /// the TTY. |
110 | /// |
111 | /// \param[in] term |
112 | /// The Terminal instance holding fd to save. |
113 | /// |
114 | /// \param[in] save_process_group |
115 | /// If \b true, save the process group settings, else do not |
116 | /// save the process group settings for a TTY. |
117 | /// |
118 | /// \return |
119 | /// Returns \b true if \a fd describes a TTY and if the state |
120 | /// was able to be saved, \b false otherwise. |
121 | bool Save(Terminal term, bool save_process_group); |
122 | |
123 | /// Restore the TTY state to the cached state. |
124 | /// |
125 | /// Restore the state of the TTY using the cached values from a previous |
126 | /// call to TerminalState::Save(int,bool). |
127 | /// |
128 | /// \return |
129 | /// Returns \b true if the TTY state was successfully restored, |
130 | /// \b false otherwise. |
131 | bool Restore() const; |
132 | |
133 | /// Test for valid cached TTY state information. |
134 | /// |
135 | /// \return |
136 | /// Returns \b true if this object has valid saved TTY state |
137 | /// settings that can be used to restore a previous state, |
138 | /// \b false otherwise. |
139 | bool IsValid() const; |
140 | |
141 | void Clear(); |
142 | |
143 | protected: |
144 | /// Test if tflags is valid. |
145 | /// |
146 | /// \return |
147 | /// Returns \b true if \a m_tflags is valid and can be restored, |
148 | /// \b false otherwise. |
149 | bool TFlagsIsValid() const; |
150 | |
151 | /// Test if ttystate is valid. |
152 | /// |
153 | /// \return |
154 | /// Returns \b true if \a m_ttystate is valid and can be |
155 | /// restored, \b false otherwise. |
156 | bool TTYStateIsValid() const; |
157 | |
158 | /// Test if the process group information is valid. |
159 | /// |
160 | /// \return |
161 | /// Returns \b true if \a m_process_group is valid and can be |
162 | /// restored, \b false otherwise. |
163 | bool ProcessGroupIsValid() const; |
164 | |
165 | // Member variables |
166 | Terminal m_tty; ///< A terminal |
167 | int m_tflags = -1; ///< Cached tflags information. |
168 | std::unique_ptr<Terminal::Data> m_data; ///< Platform-specific implementation. |
169 | lldb::pid_t m_process_group = -1; ///< Cached process group information. |
170 | }; |
171 | |
172 | } // namespace lldb_private |
173 | |
174 | #endif // LLDB_HOST_TERMINAL_H |
175 | |