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/Utility/PseudoTerminal.h"
16 #if defined(TIOCSCTTY)
17 #include <sys/ioctl.h>
20 using namespace lldb_utility;
22 //----------------------------------------------------------------------
23 // PseudoTerminal constructor
24 //----------------------------------------------------------------------
25 PseudoTerminal::PseudoTerminal () :
26 m_master_fd(invalid_fd),
27 m_slave_fd(invalid_fd)
31 //----------------------------------------------------------------------
34 // The destructor will close the master and slave file descriptors
35 // if they are valid and ownwership has not been released using the
36 // ReleaseMasterFileDescriptor() or the ReleaseSaveFileDescriptor()
38 //----------------------------------------------------------------------
39 PseudoTerminal::~PseudoTerminal ()
41 CloseMasterFileDescriptor();
42 CloseSlaveFileDescriptor();
45 //----------------------------------------------------------------------
46 // Close the master file descriptor if it is valid.
47 //----------------------------------------------------------------------
49 PseudoTerminal::CloseMasterFileDescriptor ()
53 ::close (m_master_fd);
54 m_master_fd = invalid_fd;
58 //----------------------------------------------------------------------
59 // Close the slave file descriptor if it is valid.
60 //----------------------------------------------------------------------
62 PseudoTerminal::CloseSlaveFileDescriptor ()
67 m_slave_fd = invalid_fd;
71 //----------------------------------------------------------------------
72 // Open the first available pseudo terminal with OFLAG as the
73 // permissions. The file descriptor is stored in this object and can
74 // be accessed with the MasterFileDescriptor() accessor. The
75 // ownership of the master file descriptor can be released using
76 // the ReleaseMasterFileDescriptor() accessor. If this object has
77 // a valid master files descriptor when its destructor is called, it
78 // will close the master file descriptor, therefore clients must
79 // call ReleaseMasterFileDescriptor() if they wish to use the master
80 // file descriptor after this object is out of scope or destroyed.
83 // Zero when successful, non-zero indicating an error occurred.
84 //----------------------------------------------------------------------
86 PseudoTerminal::OpenFirstAvailableMaster (int oflag, char *error_str, size_t error_len)
91 // Open the master side of a pseudo terminal
92 m_master_fd = ::posix_openpt (oflag);
96 ::strerror_r (errno, error_str, error_len);
100 // Grant access to the slave pseudo terminal
101 if (::grantpt (m_master_fd) < 0)
104 ::strerror_r (errno, error_str, error_len);
105 CloseMasterFileDescriptor ();
109 // Clear the lock flag on the slave pseudo terminal
110 if (::unlockpt (m_master_fd) < 0)
113 ::strerror_r (errno, error_str, error_len);
114 CloseMasterFileDescriptor ();
121 //----------------------------------------------------------------------
122 // Open the slave pseudo terminal for the current master pseudo
123 // terminal. A master pseudo terminal should already be valid prior to
124 // calling this function (see OpenFirstAvailableMaster()).
125 // The file descriptor is stored this object's member variables and can
126 // be accessed via the GetSlaveFileDescriptor(), or released using the
127 // ReleaseSlaveFileDescriptor() member function.
130 // Zero when successful, non-zero indicating an error occurred.
131 //----------------------------------------------------------------------
133 PseudoTerminal::OpenSlave (int oflag, char *error_str, size_t error_len)
138 CloseSlaveFileDescriptor();
140 // Open the master side of a pseudo terminal
141 const char *slave_name = GetSlaveName (error_str, error_len);
143 if (slave_name == NULL)
146 m_slave_fd = ::open (slave_name, oflag);
151 ::strerror_r (errno, error_str, error_len);
160 //----------------------------------------------------------------------
161 // Get the name of the slave pseudo terminal. A master pseudo terminal
162 // should already be valid prior to calling this function (see
163 // OpenFirstAvailableMaster()).
166 // NULL if no valid master pseudo terminal or if ptsname() fails.
167 // The name of the slave pseudo terminal as a NULL terminated C string
168 // that comes from static memory, so a copy of the string should be
169 // made as subsequent calls can change this value.
170 //----------------------------------------------------------------------
172 PseudoTerminal::GetSlaveName (char *error_str, size_t error_len) const
180 ::snprintf (error_str, error_len, "%s", "master file descriptor is invalid");
183 const char *slave_name = ::ptsname (m_master_fd);
185 if (error_str && slave_name == NULL)
186 ::strerror_r (errno, error_str, error_len);
192 //----------------------------------------------------------------------
193 // Fork a child process and have its stdio routed to a pseudo terminal.
195 // In the parent process when a valid pid is returned, the master file
196 // descriptor can be used as a read/write access to stdio of the
199 // In the child process the stdin/stdout/stderr will already be routed
200 // to the slave pseudo terminal and the master file descriptor will be
201 // closed as it is no longer needed by the child process.
203 // This class will close the file descriptors for the master/slave
204 // when the destructor is called, so be sure to call
205 // ReleaseMasterFileDescriptor() or ReleaseSlaveFileDescriptor() if any
206 // file descriptors are going to be used past the lifespan of this
210 // in the parent process: the pid of the child, or -1 if fork fails
211 // in the child process: zero
212 //----------------------------------------------------------------------
214 PseudoTerminal::Fork (char *error_str, size_t error_len)
219 pid_t pid = LLDB_INVALID_PROCESS_ID;
220 if (OpenFirstAvailableMaster (O_RDWR, error_str, error_len))
222 // Successfully opened our master pseudo terminal
229 ::strerror_r (errno, error_str, error_len);
236 if (OpenSlave (O_RDWR, error_str, error_len))
238 // Successfully opened slave
239 // We are done with the master in the child process so lets close it
240 CloseMasterFileDescriptor ();
242 #if defined(TIOCSCTTY)
243 // Acquire the controlling terminal
244 if (::ioctl (m_slave_fd, TIOCSCTTY, (char *)0) < 0)
247 ::strerror_r (errno, error_str, error_len);
250 // Duplicate all stdio file descriptors to the slave pseudo terminal
251 if (::dup2 (m_slave_fd, STDIN_FILENO) != STDIN_FILENO)
253 if (error_str && !error_str[0])
254 ::strerror_r (errno, error_str, error_len);
257 if (::dup2 (m_slave_fd, STDOUT_FILENO) != STDOUT_FILENO)
259 if (error_str && !error_str[0])
260 ::strerror_r (errno, error_str, error_len);
263 if (::dup2 (m_slave_fd, STDERR_FILENO) != STDERR_FILENO)
265 if (error_str && !error_str[0])
266 ::strerror_r (errno, error_str, error_len);
273 // Do nothing and let the pid get returned!
279 //----------------------------------------------------------------------
280 // The master file descriptor accessor. This object retains ownership
281 // of the master file descriptor when this accessor is used. Use
282 // ReleaseMasterFileDescriptor() if you wish this object to release
283 // ownership of the master file descriptor.
285 // Returns the master file descriptor, or -1 if the master file
286 // descriptor is not currently valid.
287 //----------------------------------------------------------------------
289 PseudoTerminal::GetMasterFileDescriptor () const
294 //----------------------------------------------------------------------
295 // The slave file descriptor accessor.
297 // Returns the slave file descriptor, or -1 if the slave file
298 // descriptor is not currently valid.
299 //----------------------------------------------------------------------
301 PseudoTerminal::GetSlaveFileDescriptor () const
306 //----------------------------------------------------------------------
307 // Release ownership of the master pseudo terminal file descriptor
308 // without closing it. The destructor for this class will close the
309 // master file descriptor if the ownership isn't released using this
310 // call and the master file descriptor has been opened.
311 //----------------------------------------------------------------------
313 PseudoTerminal::ReleaseMasterFileDescriptor ()
315 // Release ownership of the master pseudo terminal file
316 // descriptor without closing it. (the destructor for this
317 // class will close it otherwise!)
318 int fd = m_master_fd;
319 m_master_fd = invalid_fd;
323 //----------------------------------------------------------------------
324 // Release ownership of the slave pseudo terminal file descriptor
325 // without closing it. The destructor for this class will close the
326 // slave file descriptor if the ownership isn't released using this
327 // call and the slave file descriptor has been opened.
328 //----------------------------------------------------------------------
330 PseudoTerminal::ReleaseSlaveFileDescriptor ()
332 // Release ownership of the slave pseudo terminal file
333 // descriptor without closing it (the destructor for this
334 // class will close it otherwise!)
336 m_slave_fd = invalid_fd;