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 m_fd(fd)41 Terminal(int fd = -1) : m_fd(fd) {} 42 43 ~Terminal() = default; 44 45 bool IsATerminal() const; 46 GetFileDescriptor()47 int GetFileDescriptor() const { return m_fd; } 48 SetFileDescriptor(int fd)49 void SetFileDescriptor(int fd) { m_fd = fd; } 50 FileDescriptorIsValid()51 bool FileDescriptorIsValid() const { return m_fd != -1; } 52 Clear()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