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