1 //===-- PseudoTerminal.cpp --------------------------------------*- 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 #include "lldb/Host/PseudoTerminal.h" 11 #include "lldb/Host/Config.h" 12 13 #include <errno.h> 14 #include <stdio.h> 15 #include <stdlib.h> 16 #include <string.h> 17 #if defined(TIOCSCTTY) 18 #include <sys/ioctl.h> 19 #endif 20 21 #include "lldb/Host/PosixApi.h" 22 23 #if defined(__ANDROID__) 24 int posix_openpt(int flags); 25 #endif 26 27 using namespace lldb_private; 28 29 //---------------------------------------------------------------------- 30 // PseudoTerminal constructor 31 //---------------------------------------------------------------------- 32 PseudoTerminal::PseudoTerminal() 33 : m_master_fd(invalid_fd), m_slave_fd(invalid_fd) {} 34 35 //---------------------------------------------------------------------- 36 // Destructor 37 // 38 // The destructor will close the master and slave file descriptors 39 // if they are valid and ownership has not been released using the 40 // ReleaseMasterFileDescriptor() or the ReleaseSaveFileDescriptor() 41 // member functions. 42 //---------------------------------------------------------------------- 43 PseudoTerminal::~PseudoTerminal() { 44 CloseMasterFileDescriptor(); 45 CloseSlaveFileDescriptor(); 46 } 47 48 //---------------------------------------------------------------------- 49 // Close the master file descriptor if it is valid. 50 //---------------------------------------------------------------------- 51 void PseudoTerminal::CloseMasterFileDescriptor() { 52 if (m_master_fd >= 0) { 53 ::close(m_master_fd); 54 m_master_fd = invalid_fd; 55 } 56 } 57 58 //---------------------------------------------------------------------- 59 // Close the slave file descriptor if it is valid. 60 //---------------------------------------------------------------------- 61 void PseudoTerminal::CloseSlaveFileDescriptor() { 62 if (m_slave_fd >= 0) { 63 ::close(m_slave_fd); 64 m_slave_fd = invalid_fd; 65 } 66 } 67 68 //---------------------------------------------------------------------- 69 // Open the first available pseudo terminal with OFLAG as the 70 // permissions. The file descriptor is stored in this object and can 71 // be accessed with the MasterFileDescriptor() accessor. The 72 // ownership of the master file descriptor can be released using 73 // the ReleaseMasterFileDescriptor() accessor. If this object has 74 // a valid master files descriptor when its destructor is called, it 75 // will close the master file descriptor, therefore clients must 76 // call ReleaseMasterFileDescriptor() if they wish to use the master 77 // file descriptor after this object is out of scope or destroyed. 78 // 79 // RETURNS: 80 // True when successful, false indicating an error occurred. 81 //---------------------------------------------------------------------- 82 bool PseudoTerminal::OpenFirstAvailableMaster(int oflag, char *error_str, 83 size_t error_len) { 84 if (error_str) 85 error_str[0] = '\0'; 86 87 #if !defined(LLDB_DISABLE_POSIX) 88 // Open the master side of a pseudo terminal 89 m_master_fd = ::posix_openpt(oflag); 90 if (m_master_fd < 0) { 91 if (error_str) 92 ::strerror_r(errno, error_str, error_len); 93 return false; 94 } 95 96 // Grant access to the slave pseudo terminal 97 if (::grantpt(m_master_fd) < 0) { 98 if (error_str) 99 ::strerror_r(errno, error_str, error_len); 100 CloseMasterFileDescriptor(); 101 return false; 102 } 103 104 // Clear the lock flag on the slave pseudo terminal 105 if (::unlockpt(m_master_fd) < 0) { 106 if (error_str) 107 ::strerror_r(errno, error_str, error_len); 108 CloseMasterFileDescriptor(); 109 return false; 110 } 111 112 return true; 113 #else 114 if (error_str) 115 ::snprintf(error_str, error_len, "%s", "pseudo terminal not supported"); 116 return false; 117 #endif 118 } 119 120 //---------------------------------------------------------------------- 121 // Open the slave pseudo terminal for the current master pseudo 122 // terminal. A master pseudo terminal should already be valid prior to 123 // calling this function (see OpenFirstAvailableMaster()). 124 // The file descriptor is stored this object's member variables and can 125 // be accessed via the GetSlaveFileDescriptor(), or released using the 126 // ReleaseSlaveFileDescriptor() member function. 127 // 128 // RETURNS: 129 // True when successful, false indicating an error occurred. 130 //---------------------------------------------------------------------- 131 bool PseudoTerminal::OpenSlave(int oflag, char *error_str, size_t error_len) { 132 if (error_str) 133 error_str[0] = '\0'; 134 135 CloseSlaveFileDescriptor(); 136 137 // Open the master side of a pseudo terminal 138 const char *slave_name = GetSlaveName(error_str, error_len); 139 140 if (slave_name == nullptr) 141 return false; 142 143 m_slave_fd = ::open(slave_name, oflag); 144 145 if (m_slave_fd < 0) { 146 if (error_str) 147 ::strerror_r(errno, error_str, error_len); 148 return false; 149 } 150 151 return true; 152 } 153 154 //---------------------------------------------------------------------- 155 // Get the name of the slave pseudo terminal. A master pseudo terminal 156 // should already be valid prior to calling this function (see 157 // OpenFirstAvailableMaster()). 158 // 159 // RETURNS: 160 // NULL if no valid master pseudo terminal or if ptsname() fails. 161 // The name of the slave pseudo terminal as a NULL terminated C string 162 // that comes from static memory, so a copy of the string should be 163 // made as subsequent calls can change this value. 164 //---------------------------------------------------------------------- 165 const char *PseudoTerminal::GetSlaveName(char *error_str, 166 size_t error_len) const { 167 if (error_str) 168 error_str[0] = '\0'; 169 170 if (m_master_fd < 0) { 171 if (error_str) 172 ::snprintf(error_str, error_len, "%s", 173 "master file descriptor is invalid"); 174 return nullptr; 175 } 176 const char *slave_name = ::ptsname(m_master_fd); 177 178 if (error_str && slave_name == nullptr) 179 ::strerror_r(errno, error_str, error_len); 180 181 return slave_name; 182 } 183 184 //---------------------------------------------------------------------- 185 // Fork a child process and have its stdio routed to a pseudo terminal. 186 // 187 // In the parent process when a valid pid is returned, the master file 188 // descriptor can be used as a read/write access to stdio of the 189 // child process. 190 // 191 // In the child process the stdin/stdout/stderr will already be routed 192 // to the slave pseudo terminal and the master file descriptor will be 193 // closed as it is no longer needed by the child process. 194 // 195 // This class will close the file descriptors for the master/slave 196 // when the destructor is called, so be sure to call 197 // ReleaseMasterFileDescriptor() or ReleaseSlaveFileDescriptor() if any 198 // file descriptors are going to be used past the lifespan of this 199 // object. 200 // 201 // RETURNS: 202 // in the parent process: the pid of the child, or -1 if fork fails 203 // in the child process: zero 204 //---------------------------------------------------------------------- 205 lldb::pid_t PseudoTerminal::Fork(char *error_str, size_t error_len) { 206 if (error_str) 207 error_str[0] = '\0'; 208 pid_t pid = LLDB_INVALID_PROCESS_ID; 209 #if !defined(LLDB_DISABLE_POSIX) 210 int flags = O_RDWR; 211 flags |= O_CLOEXEC; 212 if (OpenFirstAvailableMaster(flags, error_str, error_len)) { 213 // Successfully opened our master pseudo terminal 214 215 pid = ::fork(); 216 if (pid < 0) { 217 // Fork failed 218 if (error_str) 219 ::strerror_r(errno, error_str, error_len); 220 } else if (pid == 0) { 221 // Child Process 222 ::setsid(); 223 224 if (OpenSlave(O_RDWR, error_str, error_len)) { 225 // Successfully opened slave 226 227 // Master FD should have O_CLOEXEC set, but let's close it just in 228 // case... 229 CloseMasterFileDescriptor(); 230 231 #if defined(TIOCSCTTY) 232 // Acquire the controlling terminal 233 if (::ioctl(m_slave_fd, TIOCSCTTY, (char *)0) < 0) { 234 if (error_str) 235 ::strerror_r(errno, error_str, error_len); 236 } 237 #endif 238 // Duplicate all stdio file descriptors to the slave pseudo terminal 239 if (::dup2(m_slave_fd, STDIN_FILENO) != STDIN_FILENO) { 240 if (error_str && !error_str[0]) 241 ::strerror_r(errno, error_str, error_len); 242 } 243 244 if (::dup2(m_slave_fd, STDOUT_FILENO) != STDOUT_FILENO) { 245 if (error_str && !error_str[0]) 246 ::strerror_r(errno, error_str, error_len); 247 } 248 249 if (::dup2(m_slave_fd, STDERR_FILENO) != STDERR_FILENO) { 250 if (error_str && !error_str[0]) 251 ::strerror_r(errno, error_str, error_len); 252 } 253 } 254 } else { 255 // Parent Process 256 // Do nothing and let the pid get returned! 257 } 258 } 259 #endif 260 return pid; 261 } 262 263 //---------------------------------------------------------------------- 264 // The master file descriptor accessor. This object retains ownership 265 // of the master file descriptor when this accessor is used. Use 266 // ReleaseMasterFileDescriptor() if you wish this object to release 267 // ownership of the master file descriptor. 268 // 269 // Returns the master file descriptor, or -1 if the master file 270 // descriptor is not currently valid. 271 //---------------------------------------------------------------------- 272 int PseudoTerminal::GetMasterFileDescriptor() const { return m_master_fd; } 273 274 //---------------------------------------------------------------------- 275 // The slave file descriptor accessor. 276 // 277 // Returns the slave file descriptor, or -1 if the slave file 278 // descriptor is not currently valid. 279 //---------------------------------------------------------------------- 280 int PseudoTerminal::GetSlaveFileDescriptor() const { return m_slave_fd; } 281 282 //---------------------------------------------------------------------- 283 // Release ownership of the master pseudo terminal file descriptor 284 // without closing it. The destructor for this class will close the 285 // master file descriptor if the ownership isn't released using this 286 // call and the master file descriptor has been opened. 287 //---------------------------------------------------------------------- 288 int PseudoTerminal::ReleaseMasterFileDescriptor() { 289 // Release ownership of the master pseudo terminal file 290 // descriptor without closing it. (the destructor for this 291 // class will close it otherwise!) 292 int fd = m_master_fd; 293 m_master_fd = invalid_fd; 294 return fd; 295 } 296 297 //---------------------------------------------------------------------- 298 // Release ownership of the slave pseudo terminal file descriptor 299 // without closing it. The destructor for this class will close the 300 // slave file descriptor if the ownership isn't released using this 301 // call and the slave file descriptor has been opened. 302 //---------------------------------------------------------------------- 303 int PseudoTerminal::ReleaseSlaveFileDescriptor() { 304 // Release ownership of the slave pseudo terminal file 305 // descriptor without closing it (the destructor for this 306 // class will close it otherwise!) 307 int fd = m_slave_fd; 308 m_slave_fd = invalid_fd; 309 return fd; 310 } 311