1 //===-- PseudoTerminal.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_PSEUDOTERMINAL_H 10 #define LLDB_HOST_PSEUDOTERMINAL_H 11 12 #include <fcntl.h> 13 #include <string> 14 15 #include "lldb/lldb-defines.h" 16 17 namespace lldb_private { 18 19 /// \class PseudoTerminal PseudoTerminal.h "lldb/Host/PseudoTerminal.h" 20 /// A pseudo terminal helper class. 21 /// 22 /// The pseudo terminal class abstracts the use of pseudo terminals on the 23 /// host system. 24 class PseudoTerminal { 25 public: 26 enum { 27 invalid_fd = -1 ///< Invalid file descriptor value 28 }; 29 30 /// Default constructor 31 /// 32 /// Constructs this object with invalid master and slave file descriptors. 33 PseudoTerminal(); 34 35 /// Destructor 36 /// 37 /// The destructor will close the master and slave file descriptors if they 38 /// are valid and ownership has not been released using one of: @li 39 /// PseudoTerminal::ReleaseMasterFileDescriptor() @li 40 /// PseudoTerminal::ReleaseSaveFileDescriptor() 41 ~PseudoTerminal(); 42 43 /// Close the master file descriptor if it is valid. 44 void CloseMasterFileDescriptor(); 45 46 /// Close the slave file descriptor if it is valid. 47 void CloseSlaveFileDescriptor(); 48 49 /// Fork a child process that uses pseudo terminals for its stdio. 50 /// 51 /// In the parent process, a call to this function results in a pid being 52 /// returned. If the pid is valid, the master file descriptor can be used 53 /// for read/write access to stdio of the child process. 54 /// 55 /// In the child process the stdin/stdout/stderr will already be routed to 56 /// the slave pseudo terminal and the master file descriptor will be closed 57 /// as it is no longer needed by the child process. 58 /// 59 /// This class will close the file descriptors for the master/slave when the 60 /// destructor is called. The file handles can be released using either: @li 61 /// PseudoTerminal::ReleaseMasterFileDescriptor() @li 62 /// PseudoTerminal::ReleaseSaveFileDescriptor() 63 /// 64 /// \param[out] error 65 /// An pointer to an error that can describe any errors that 66 /// occur. This can be NULL if no error status is desired. 67 /// 68 /// \return 69 /// \li \b Parent process: a child process ID that is greater 70 /// than zero, or -1 if the fork fails. 71 /// \li \b Child process: zero. 72 lldb::pid_t Fork(char *error_str, size_t error_len); 73 74 /// The master file descriptor accessor. 75 /// 76 /// This object retains ownership of the master file descriptor when this 77 /// accessor is used. Users can call the member function 78 /// PseudoTerminal::ReleaseMasterFileDescriptor() if this object should 79 /// release ownership of the slave file descriptor. 80 /// 81 /// \return 82 /// The master file descriptor, or PseudoTerminal::invalid_fd 83 /// if the master file descriptor is not currently valid. 84 /// 85 /// \see PseudoTerminal::ReleaseMasterFileDescriptor() 86 int GetMasterFileDescriptor() const; 87 88 /// The slave file descriptor accessor. 89 /// 90 /// This object retains ownership of the slave file descriptor when this 91 /// accessor is used. Users can call the member function 92 /// PseudoTerminal::ReleaseSlaveFileDescriptor() if this object should 93 /// release ownership of the slave file descriptor. 94 /// 95 /// \return 96 /// The slave file descriptor, or PseudoTerminal::invalid_fd 97 /// if the slave file descriptor is not currently valid. 98 /// 99 /// \see PseudoTerminal::ReleaseSlaveFileDescriptor() 100 int GetSlaveFileDescriptor() const; 101 102 /// Get the name of the slave pseudo terminal. 103 /// 104 /// A master pseudo terminal should already be valid prior to 105 /// calling this function. 106 /// 107 /// \param[out] error 108 /// An pointer to an error that can describe any errors that 109 /// occur. This can be NULL if no error status is desired. 110 /// 111 /// \return 112 /// The name of the slave pseudo terminal as a NULL terminated 113 /// C. This string that comes from static memory, so a copy of 114 /// the string should be made as subsequent calls can change 115 /// this value. NULL is returned if this object doesn't have 116 /// a valid master pseudo terminal opened or if the call to 117 /// \c ptsname() fails. 118 /// 119 /// \see PseudoTerminal::OpenFirstAvailableMaster() 120 const char *GetSlaveName(char *error_str, size_t error_len) const; 121 122 /// Open the first available pseudo terminal. 123 /// 124 /// Opens the first available pseudo terminal with \a oflag as the 125 /// permissions. The opened master file descriptor is stored in this object 126 /// and can be accessed by calling the 127 /// PseudoTerminal::GetMasterFileDescriptor() accessor. Clients can call the 128 /// PseudoTerminal::ReleaseMasterFileDescriptor() accessor function if they 129 /// wish to use the master file descriptor beyond the lifespan of this 130 /// object. 131 /// 132 /// If this object still has a valid master file descriptor when its 133 /// destructor is called, it will close it. 134 /// 135 /// \param[in] oflag 136 /// Flags to use when calling \c posix_openpt(\a oflag). 137 /// A value of "O_RDWR|O_NOCTTY" is suggested. 138 /// 139 /// \param[out] error 140 /// An pointer to an error that can describe any errors that 141 /// occur. This can be NULL if no error status is desired. 142 /// 143 /// \return 144 /// \li \b true when the master files descriptor is 145 /// successfully opened. 146 /// \li \b false if anything goes wrong. 147 /// 148 /// \see PseudoTerminal::GetMasterFileDescriptor() @see 149 /// PseudoTerminal::ReleaseMasterFileDescriptor() 150 bool OpenFirstAvailableMaster(int oflag, char *error_str, size_t error_len); 151 152 /// Open the slave for the current master pseudo terminal. 153 /// 154 /// A master pseudo terminal should already be valid prior to 155 /// calling this function. The opened slave file descriptor is stored in 156 /// this object and can be accessed by calling the 157 /// PseudoTerminal::GetSlaveFileDescriptor() accessor. Clients can call the 158 /// PseudoTerminal::ReleaseSlaveFileDescriptor() accessor function if they 159 /// wish to use the slave file descriptor beyond the lifespan of this 160 /// object. 161 /// 162 /// If this object still has a valid slave file descriptor when its 163 /// destructor is called, it will close it. 164 /// 165 /// \param[in] oflag 166 /// Flags to use when calling \c open(\a oflag). 167 /// 168 /// \param[out] error 169 /// An pointer to an error that can describe any errors that 170 /// occur. This can be NULL if no error status is desired. 171 /// 172 /// \return 173 /// \li \b true when the master files descriptor is 174 /// successfully opened. 175 /// \li \b false if anything goes wrong. 176 /// 177 /// \see PseudoTerminal::OpenFirstAvailableMaster() @see 178 /// PseudoTerminal::GetSlaveFileDescriptor() @see 179 /// PseudoTerminal::ReleaseSlaveFileDescriptor() 180 bool OpenSlave(int oflag, char *error_str, size_t error_len); 181 182 /// Release the master file descriptor. 183 /// 184 /// Releases ownership of the master pseudo terminal file descriptor without 185 /// closing it. The destructor for this class will close the master file 186 /// descriptor if the ownership isn't released using this call and the 187 /// master file descriptor has been opened. 188 /// 189 /// \return 190 /// The master file descriptor, or PseudoTerminal::invalid_fd 191 /// if the mast file descriptor is not currently valid. 192 int ReleaseMasterFileDescriptor(); 193 194 /// Release the slave file descriptor. 195 /// 196 /// Release ownership of the slave pseudo terminal file descriptor without 197 /// closing it. The destructor for this class will close the slave file 198 /// descriptor if the ownership isn't released using this call and the slave 199 /// file descriptor has been opened. 200 /// 201 /// \return 202 /// The slave file descriptor, or PseudoTerminal::invalid_fd 203 /// if the slave file descriptor is not currently valid. 204 int ReleaseSlaveFileDescriptor(); 205 206 protected: 207 // Member variables 208 int m_master_fd; ///< The file descriptor for the master. 209 int m_slave_fd; ///< The file descriptor for the slave. 210 211 private: 212 DISALLOW_COPY_AND_ASSIGN(PseudoTerminal); 213 }; 214 215 } // namespace lldb_private 216 217 #endif // #ifndef liblldb_PseudoTerminal_h_ 218