blob: 5c320c2d4b3055101134a088758de5c217b91be6 [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- 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
Jason Molendaa34a0c62010-06-09 21:28:42 +000010#include "lldb/Utility/PseudoTerminal.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000011#include "lldb/Host/Config.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000012
13#include <errno.h>
Kate Stoneb9c1b512016-09-06 20:57:50 +000014#include <stdio.h>
Chris Lattner30fdc8d2010-06-08 16:52:24 +000015#include <stdlib.h>
16#include <string.h>
Greg Clayton000aeb82011-02-09 17:41:27 +000017#if defined(TIOCSCTTY)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000018#include <sys/ioctl.h>
Greg Clayton000aeb82011-02-09 17:41:27 +000019#endif
Chris Lattner30fdc8d2010-06-08 16:52:24 +000020
Zachary Turnerf343968f2016-08-09 23:06:08 +000021#include "lldb/Host/PosixApi.h"
Virgile Bellob2f1fb22013-08-23 12:44:05 +000022
Zachary Turnerf343968f2016-08-09 23:06:08 +000023#if defined(__ANDROID_NDK__)
Vince Harron8b335672015-05-12 01:10:56 +000024int posix_openpt(int flags);
Virgile Bellob2f1fb22013-08-23 12:44:05 +000025#endif
26
Chris Lattner30fdc8d2010-06-08 16:52:24 +000027using namespace lldb_utility;
28
29//----------------------------------------------------------------------
30// PseudoTerminal constructor
31//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +000032PseudoTerminal::PseudoTerminal()
33 : m_master_fd(invalid_fd), m_slave_fd(invalid_fd) {}
Chris Lattner30fdc8d2010-06-08 16:52:24 +000034
35//----------------------------------------------------------------------
36// Destructor
37//
38// The destructor will close the master and slave file descriptors
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +000039// if they are valid and ownership has not been released using the
Chris Lattner30fdc8d2010-06-08 16:52:24 +000040// ReleaseMasterFileDescriptor() or the ReleaseSaveFileDescriptor()
41// member functions.
42//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +000043PseudoTerminal::~PseudoTerminal() {
44 CloseMasterFileDescriptor();
45 CloseSlaveFileDescriptor();
Chris Lattner30fdc8d2010-06-08 16:52:24 +000046}
47
48//----------------------------------------------------------------------
49// Close the master file descriptor if it is valid.
50//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +000051void PseudoTerminal::CloseMasterFileDescriptor() {
52 if (m_master_fd >= 0) {
Kate Stoneb9c1b512016-09-06 20:57:50 +000053 ::close(m_master_fd);
Kate Stoneb9c1b512016-09-06 20:57:50 +000054 m_master_fd = invalid_fd;
55 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +000056}
57
58//----------------------------------------------------------------------
59// Close the slave file descriptor if it is valid.
60//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +000061void PseudoTerminal::CloseSlaveFileDescriptor() {
62 if (m_slave_fd >= 0) {
63 ::close(m_slave_fd);
64 m_slave_fd = invalid_fd;
65 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +000066}
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:
Zachary Turner046bbaf2016-11-02 17:42:12 +000080// True when successful, false indicating an error occurred.
Chris Lattner30fdc8d2010-06-08 16:52:24 +000081//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +000082bool PseudoTerminal::OpenFirstAvailableMaster(int oflag, char *error_str,
83 size_t error_len) {
84 if (error_str)
85 error_str[0] = '\0';
86
Zachary Turner046bbaf2016-11-02 17:42:12 +000087#if !defined(LLDB_DISABLE_POSIX)
Kate Stoneb9c1b512016-09-06 20:57:50 +000088 // Open the master side of a pseudo terminal
89 m_master_fd = ::posix_openpt(oflag);
90 if (m_master_fd < 0) {
Chris Lattner30fdc8d2010-06-08 16:52:24 +000091 if (error_str)
Kate Stoneb9c1b512016-09-06 20:57:50 +000092 ::strerror_r(errno, error_str, error_len);
93 return false;
94 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +000095
Kate Stoneb9c1b512016-09-06 20:57:50 +000096 // 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 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000103
Kate Stoneb9c1b512016-09-06 20:57:50 +0000104 // 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 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000111
Kate Stoneb9c1b512016-09-06 20:57:50 +0000112 return true;
Zachary Turner046bbaf2016-11-02 17:42:12 +0000113#else
114 if (error_str)
115 ::snprintf(error_str, error_len, "%s",
116 "pseudo terminal not supported");
117 return false;
118#endif
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000119}
120
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.
128//
129// RETURNS:
Zachary Turner046bbaf2016-11-02 17:42:12 +0000130// True when successful, false indicating an error occurred.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000131//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000132bool PseudoTerminal::OpenSlave(int oflag, char *error_str, size_t error_len) {
133 if (error_str)
134 error_str[0] = '\0';
135
136 CloseSlaveFileDescriptor();
137
138 // Open the master side of a pseudo terminal
139 const char *slave_name = GetSlaveName(error_str, error_len);
140
141 if (slave_name == nullptr)
142 return false;
143
144 m_slave_fd = ::open(slave_name, oflag);
145
146 if (m_slave_fd < 0) {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000147 if (error_str)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000148 ::strerror_r(errno, error_str, error_len);
149 return false;
150 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000151
Kate Stoneb9c1b512016-09-06 20:57:50 +0000152 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000153}
154
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000155//----------------------------------------------------------------------
156// Get the name of the slave pseudo terminal. A master pseudo terminal
157// should already be valid prior to calling this function (see
158// OpenFirstAvailableMaster()).
159//
160// RETURNS:
161// NULL if no valid master pseudo terminal or if ptsname() fails.
162// The name of the slave pseudo terminal as a NULL terminated C string
163// that comes from static memory, so a copy of the string should be
164// made as subsequent calls can change this value.
165//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000166const char *PseudoTerminal::GetSlaveName(char *error_str,
167 size_t error_len) const {
168 if (error_str)
169 error_str[0] = '\0';
170
171 if (m_master_fd < 0) {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000172 if (error_str)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000173 ::snprintf(error_str, error_len, "%s",
174 "master file descriptor is invalid");
175 return nullptr;
176 }
177 const char *slave_name = ::ptsname(m_master_fd);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000178
Kate Stoneb9c1b512016-09-06 20:57:50 +0000179 if (error_str && slave_name == nullptr)
180 ::strerror_r(errno, error_str, error_len);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000181
Kate Stoneb9c1b512016-09-06 20:57:50 +0000182 return slave_name;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000183}
184
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000185//----------------------------------------------------------------------
186// Fork a child process and have its stdio routed to a pseudo terminal.
187//
188// In the parent process when a valid pid is returned, the master file
189// descriptor can be used as a read/write access to stdio of the
190// child process.
191//
192// In the child process the stdin/stdout/stderr will already be routed
193// to the slave pseudo terminal and the master file descriptor will be
194// closed as it is no longer needed by the child process.
195//
196// This class will close the file descriptors for the master/slave
197// when the destructor is called, so be sure to call
198// ReleaseMasterFileDescriptor() or ReleaseSlaveFileDescriptor() if any
199// file descriptors are going to be used past the lifespan of this
200// object.
201//
202// RETURNS:
203// in the parent process: the pid of the child, or -1 if fork fails
204// in the child process: zero
205//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000206lldb::pid_t PseudoTerminal::Fork(char *error_str, size_t error_len) {
207 if (error_str)
208 error_str[0] = '\0';
209 pid_t pid = LLDB_INVALID_PROCESS_ID;
Zachary Turner48b475c2015-04-02 20:57:38 +0000210#if !defined(LLDB_DISABLE_POSIX)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000211 int flags = O_RDWR;
212 flags |= O_CLOEXEC;
213 if (OpenFirstAvailableMaster(flags, error_str, error_len)) {
214 // Successfully opened our master pseudo terminal
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000215
Kate Stoneb9c1b512016-09-06 20:57:50 +0000216 pid = ::fork();
217 if (pid < 0) {
218 // Fork failed
219 if (error_str)
220 ::strerror_r(errno, error_str, error_len);
221 } else if (pid == 0) {
222 // Child Process
223 ::setsid();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000224
Kate Stoneb9c1b512016-09-06 20:57:50 +0000225 if (OpenSlave(O_RDWR, error_str, error_len)) {
226 // Successfully opened slave
Pavel Labathb4bf1c62015-02-09 11:37:56 +0000227
Kate Stoneb9c1b512016-09-06 20:57:50 +0000228 // Master FD should have O_CLOEXEC set, but let's close it just in
229 // case...
230 CloseMasterFileDescriptor();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000231
Greg Clayton000aeb82011-02-09 17:41:27 +0000232#if defined(TIOCSCTTY)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000233 // Acquire the controlling terminal
234 if (::ioctl(m_slave_fd, TIOCSCTTY, (char *)0) < 0) {
235 if (error_str)
236 ::strerror_r(errno, error_str, error_len);
237 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000238#endif
Kate Stoneb9c1b512016-09-06 20:57:50 +0000239 // Duplicate all stdio file descriptors to the slave pseudo terminal
240 if (::dup2(m_slave_fd, STDIN_FILENO) != STDIN_FILENO) {
241 if (error_str && !error_str[0])
242 ::strerror_r(errno, error_str, error_len);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000243 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000244
245 if (::dup2(m_slave_fd, STDOUT_FILENO) != STDOUT_FILENO) {
246 if (error_str && !error_str[0])
247 ::strerror_r(errno, error_str, error_len);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000248 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000249
250 if (::dup2(m_slave_fd, STDERR_FILENO) != STDERR_FILENO) {
251 if (error_str && !error_str[0])
252 ::strerror_r(errno, error_str, error_len);
253 }
254 }
255 } else {
256 // Parent Process
257 // Do nothing and let the pid get returned!
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000258 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000259 }
Zachary Turner48b475c2015-04-02 20:57:38 +0000260#endif
Kate Stoneb9c1b512016-09-06 20:57:50 +0000261 return pid;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000262}
263
264//----------------------------------------------------------------------
265// The master file descriptor accessor. This object retains ownership
266// of the master file descriptor when this accessor is used. Use
267// ReleaseMasterFileDescriptor() if you wish this object to release
268// ownership of the master file descriptor.
269//
270// Returns the master file descriptor, or -1 if the master file
271// descriptor is not currently valid.
272//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000273int PseudoTerminal::GetMasterFileDescriptor() const { return m_master_fd; }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000274
275//----------------------------------------------------------------------
276// The slave file descriptor accessor.
277//
278// Returns the slave file descriptor, or -1 if the slave file
279// descriptor is not currently valid.
280//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000281int PseudoTerminal::GetSlaveFileDescriptor() const { return m_slave_fd; }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000282
283//----------------------------------------------------------------------
284// Release ownership of the master pseudo terminal file descriptor
285// without closing it. The destructor for this class will close the
286// master file descriptor if the ownership isn't released using this
287// call and the master file descriptor has been opened.
288//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000289int PseudoTerminal::ReleaseMasterFileDescriptor() {
290 // Release ownership of the master pseudo terminal file
291 // descriptor without closing it. (the destructor for this
292 // class will close it otherwise!)
293 int fd = m_master_fd;
294 m_master_fd = invalid_fd;
295 return fd;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000296}
297
298//----------------------------------------------------------------------
299// Release ownership of the slave pseudo terminal file descriptor
300// without closing it. The destructor for this class will close the
301// slave file descriptor if the ownership isn't released using this
302// call and the slave file descriptor has been opened.
303//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000304int PseudoTerminal::ReleaseSlaveFileDescriptor() {
305 // Release ownership of the slave pseudo terminal file
306 // descriptor without closing it (the destructor for this
307 // class will close it otherwise!)
308 int fd = m_slave_fd;
309 m_slave_fd = invalid_fd;
310 return fd;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000311}