1 //===-- PseudoTerminal.cpp --------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "lldb/Host/Config.h"
11 #include "lldb/Utility/PseudoTerminal.h"
17 #if defined(TIOCSCTTY)
18 #include <sys/ioctl.h>
22 #include "lldb/Host/windows/win32.h"
23 typedef uint32_t pid_t;
25 int posix_openpt(int flag) { return 0; }
27 int strerror_r(int errnum, char *buf, size_t buflen) { return 0; }
29 int unlockpt(int fd) { return 0; }
30 int grantpt(int fd) { return 0; }
31 char *ptsname(int fd) { return 0; }
33 pid_t fork(void) { return 0; }
34 pid_t setsid(void) { return 0; }
35 #elif defined(__ANDROID_NDK__)
36 #include "lldb/Host/android/Android.h"
37 int posix_openpt(int flags);
40 using namespace lldb_utility;
42 //----------------------------------------------------------------------
43 // PseudoTerminal constructor
44 //----------------------------------------------------------------------
45 PseudoTerminal::PseudoTerminal () :
46 m_master_fd(invalid_fd),
47 m_slave_fd(invalid_fd)
51 //----------------------------------------------------------------------
54 // The destructor will close the master and slave file descriptors
55 // if they are valid and ownership has not been released using the
56 // ReleaseMasterFileDescriptor() or the ReleaseSaveFileDescriptor()
58 //----------------------------------------------------------------------
59 PseudoTerminal::~PseudoTerminal ()
61 CloseMasterFileDescriptor();
62 CloseSlaveFileDescriptor();
65 //----------------------------------------------------------------------
66 // Close the master file descriptor if it is valid.
67 //----------------------------------------------------------------------
69 PseudoTerminal::CloseMasterFileDescriptor ()
73 // Don't call 'close' on m_master_fd for Windows as a dummy implementation of
74 // posix_openpt above always gives it a 0 value.
76 ::close (m_master_fd);
78 m_master_fd = invalid_fd;
82 //----------------------------------------------------------------------
83 // Close the slave file descriptor if it is valid.
84 //----------------------------------------------------------------------
86 PseudoTerminal::CloseSlaveFileDescriptor ()
91 m_slave_fd = invalid_fd;
95 //----------------------------------------------------------------------
96 // Open the first available pseudo terminal with OFLAG as the
97 // permissions. The file descriptor is stored in this object and can
98 // be accessed with the MasterFileDescriptor() accessor. The
99 // ownership of the master file descriptor can be released using
100 // the ReleaseMasterFileDescriptor() accessor. If this object has
101 // a valid master files descriptor when its destructor is called, it
102 // will close the master file descriptor, therefore clients must
103 // call ReleaseMasterFileDescriptor() if they wish to use the master
104 // file descriptor after this object is out of scope or destroyed.
107 // Zero when successful, non-zero indicating an error occurred.
108 //----------------------------------------------------------------------
110 PseudoTerminal::OpenFirstAvailableMaster (int oflag, char *error_str, size_t error_len)
115 // Open the master side of a pseudo terminal
116 m_master_fd = ::posix_openpt (oflag);
120 ::strerror_r (errno, error_str, error_len);
124 // Grant access to the slave pseudo terminal
125 if (::grantpt (m_master_fd) < 0)
128 ::strerror_r (errno, error_str, error_len);
129 CloseMasterFileDescriptor ();
133 // Clear the lock flag on the slave pseudo terminal
134 if (::unlockpt (m_master_fd) < 0)
137 ::strerror_r (errno, error_str, error_len);
138 CloseMasterFileDescriptor ();
145 //----------------------------------------------------------------------
146 // Open the slave pseudo terminal for the current master pseudo
147 // terminal. A master pseudo terminal should already be valid prior to
148 // calling this function (see OpenFirstAvailableMaster()).
149 // The file descriptor is stored this object's member variables and can
150 // be accessed via the GetSlaveFileDescriptor(), or released using the
151 // ReleaseSlaveFileDescriptor() member function.
154 // Zero when successful, non-zero indicating an error occurred.
155 //----------------------------------------------------------------------
157 PseudoTerminal::OpenSlave (int oflag, char *error_str, size_t error_len)
162 CloseSlaveFileDescriptor();
164 // Open the master side of a pseudo terminal
165 const char *slave_name = GetSlaveName (error_str, error_len);
167 if (slave_name == nullptr)
170 m_slave_fd = ::open (slave_name, oflag);
175 ::strerror_r (errno, error_str, error_len);
184 //----------------------------------------------------------------------
185 // Get the name of the slave pseudo terminal. A master pseudo terminal
186 // should already be valid prior to calling this function (see
187 // OpenFirstAvailableMaster()).
190 // NULL if no valid master pseudo terminal or if ptsname() fails.
191 // The name of the slave pseudo terminal as a NULL terminated C string
192 // that comes from static memory, so a copy of the string should be
193 // made as subsequent calls can change this value.
194 //----------------------------------------------------------------------
196 PseudoTerminal::GetSlaveName (char *error_str, size_t error_len) const
204 ::snprintf (error_str, error_len, "%s", "master file descriptor is invalid");
207 const char *slave_name = ::ptsname (m_master_fd);
209 if (error_str && slave_name == nullptr)
210 ::strerror_r (errno, error_str, error_len);
216 //----------------------------------------------------------------------
217 // Fork a child process and have its stdio routed to a pseudo terminal.
219 // In the parent process when a valid pid is returned, the master file
220 // descriptor can be used as a read/write access to stdio of the
223 // In the child process the stdin/stdout/stderr will already be routed
224 // to the slave pseudo terminal and the master file descriptor will be
225 // closed as it is no longer needed by the child process.
227 // This class will close the file descriptors for the master/slave
228 // when the destructor is called, so be sure to call
229 // ReleaseMasterFileDescriptor() or ReleaseSlaveFileDescriptor() if any
230 // file descriptors are going to be used past the lifespan of this
234 // in the parent process: the pid of the child, or -1 if fork fails
235 // in the child process: zero
236 //----------------------------------------------------------------------
238 PseudoTerminal::Fork (char *error_str, size_t error_len)
242 pid_t pid = LLDB_INVALID_PROCESS_ID;
243 #if !defined(LLDB_DISABLE_POSIX)
246 if (OpenFirstAvailableMaster (flags, error_str, error_len))
248 // Successfully opened our master pseudo terminal
255 ::strerror_r (errno, error_str, error_len);
262 if (OpenSlave (O_RDWR, error_str, error_len))
264 // Successfully opened slave
266 // Master FD should have O_CLOEXEC set, but let's close it just in case...
267 CloseMasterFileDescriptor ();
269 #if defined(TIOCSCTTY)
270 // Acquire the controlling terminal
271 if (::ioctl (m_slave_fd, TIOCSCTTY, (char *)0) < 0)
274 ::strerror_r (errno, error_str, error_len);
277 // Duplicate all stdio file descriptors to the slave pseudo terminal
278 if (::dup2 (m_slave_fd, STDIN_FILENO) != STDIN_FILENO)
280 if (error_str && !error_str[0])
281 ::strerror_r (errno, error_str, error_len);
284 if (::dup2 (m_slave_fd, STDOUT_FILENO) != STDOUT_FILENO)
286 if (error_str && !error_str[0])
287 ::strerror_r (errno, error_str, error_len);
290 if (::dup2 (m_slave_fd, STDERR_FILENO) != STDERR_FILENO)
292 if (error_str && !error_str[0])
293 ::strerror_r (errno, error_str, error_len);
300 // Do nothing and let the pid get returned!
307 //----------------------------------------------------------------------
308 // The master file descriptor accessor. This object retains ownership
309 // of the master file descriptor when this accessor is used. Use
310 // ReleaseMasterFileDescriptor() if you wish this object to release
311 // ownership of the master file descriptor.
313 // Returns the master file descriptor, or -1 if the master file
314 // descriptor is not currently valid.
315 //----------------------------------------------------------------------
317 PseudoTerminal::GetMasterFileDescriptor () const
322 //----------------------------------------------------------------------
323 // The slave file descriptor accessor.
325 // Returns the slave file descriptor, or -1 if the slave file
326 // descriptor is not currently valid.
327 //----------------------------------------------------------------------
329 PseudoTerminal::GetSlaveFileDescriptor () const
334 //----------------------------------------------------------------------
335 // Release ownership of the master pseudo terminal file descriptor
336 // without closing it. The destructor for this class will close the
337 // master file descriptor if the ownership isn't released using this
338 // call and the master file descriptor has been opened.
339 //----------------------------------------------------------------------
341 PseudoTerminal::ReleaseMasterFileDescriptor ()
343 // Release ownership of the master pseudo terminal file
344 // descriptor without closing it. (the destructor for this
345 // class will close it otherwise!)
346 int fd = m_master_fd;
347 m_master_fd = invalid_fd;
351 //----------------------------------------------------------------------
352 // Release ownership of the slave pseudo terminal file descriptor
353 // without closing it. The destructor for this class will close the
354 // slave file descriptor if the ownership isn't released using this
355 // call and the slave file descriptor has been opened.
356 //----------------------------------------------------------------------
358 PseudoTerminal::ReleaseSlaveFileDescriptor ()
360 // Release ownership of the slave pseudo terminal file
361 // descriptor without closing it (the destructor for this
362 // class will close it otherwise!)
364 m_slave_fd = invalid_fd;