blob: e90955d37d4c3d4742c0122093eff85b58fcb822 [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"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000011
12#include <errno.h>
13#include <stdlib.h>
14#include <string.h>
Eli Friedmanf254f8b2010-06-09 09:38:08 +000015#include <stdio.h>
Greg Clayton000aeb82011-02-09 17:41:27 +000016#if defined(TIOCSCTTY)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000017#include <sys/ioctl.h>
Greg Clayton000aeb82011-02-09 17:41:27 +000018#endif
Chris Lattner30fdc8d2010-06-08 16:52:24 +000019
Virgile Bellob2f1fb22013-08-23 12:44:05 +000020#ifdef _WIN32
21#include "lldb/Host/windows/win32.h"
Deepak Panickal9b35cf52014-07-01 17:57:19 +000022typedef uint32_t pid_t;
Virgile Bellob2f1fb22013-08-23 12:44:05 +000023// empty functions
24int posix_openpt(int flag) { return 0; }
25
26int strerror_r(int errnum, char *buf, size_t buflen) { return 0; }
27
28int unlockpt(int fd) { return 0; }
29int grantpt(int fd) { return 0; }
30char *ptsname(int fd) { return 0; }
31
32pid_t fork(void) { return 0; }
33pid_t setsid(void) { return 0; }
Shawn Best8da0bf32014-11-08 01:41:49 +000034#elif defined(__ANDROID_NDK__)
35#include "lldb/Host/android/Android.h"
Virgile Bellob2f1fb22013-08-23 12:44:05 +000036#endif
37
Chris Lattner30fdc8d2010-06-08 16:52:24 +000038using namespace lldb_utility;
39
40//----------------------------------------------------------------------
41// PseudoTerminal constructor
42//----------------------------------------------------------------------
43PseudoTerminal::PseudoTerminal () :
44 m_master_fd(invalid_fd),
45 m_slave_fd(invalid_fd)
46{
47}
48
49//----------------------------------------------------------------------
50// Destructor
51//
52// The destructor will close the master and slave file descriptors
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +000053// if they are valid and ownership has not been released using the
Chris Lattner30fdc8d2010-06-08 16:52:24 +000054// ReleaseMasterFileDescriptor() or the ReleaseSaveFileDescriptor()
55// member functions.
56//----------------------------------------------------------------------
57PseudoTerminal::~PseudoTerminal ()
58{
59 CloseMasterFileDescriptor();
60 CloseSlaveFileDescriptor();
61}
62
63//----------------------------------------------------------------------
64// Close the master file descriptor if it is valid.
65//----------------------------------------------------------------------
66void
67PseudoTerminal::CloseMasterFileDescriptor ()
68{
69 if (m_master_fd >= 0)
70 {
Hafiz Abid Qadeerf2896282014-10-27 19:27:00 +000071 // Don't call 'close' on m_master_fd for Windows as a dummy implementation of
72 // posix_openpt above always gives it a 0 value.
73#ifndef _WIN32
Chris Lattner30fdc8d2010-06-08 16:52:24 +000074 ::close (m_master_fd);
Hafiz Abid Qadeerf2896282014-10-27 19:27:00 +000075#endif
Chris Lattner30fdc8d2010-06-08 16:52:24 +000076 m_master_fd = invalid_fd;
77 }
78}
79
80//----------------------------------------------------------------------
81// Close the slave file descriptor if it is valid.
82//----------------------------------------------------------------------
83void
84PseudoTerminal::CloseSlaveFileDescriptor ()
85{
86 if (m_slave_fd >= 0)
87 {
88 ::close (m_slave_fd);
89 m_slave_fd = invalid_fd;
90 }
91}
92
93//----------------------------------------------------------------------
94// Open the first available pseudo terminal with OFLAG as the
95// permissions. The file descriptor is stored in this object and can
96// be accessed with the MasterFileDescriptor() accessor. The
97// ownership of the master file descriptor can be released using
98// the ReleaseMasterFileDescriptor() accessor. If this object has
99// a valid master files descriptor when its destructor is called, it
100// will close the master file descriptor, therefore clients must
101// call ReleaseMasterFileDescriptor() if they wish to use the master
102// file descriptor after this object is out of scope or destroyed.
103//
104// RETURNS:
105// Zero when successful, non-zero indicating an error occurred.
106//----------------------------------------------------------------------
107bool
108PseudoTerminal::OpenFirstAvailableMaster (int oflag, char *error_str, size_t error_len)
109{
110 if (error_str)
111 error_str[0] = '\0';
112
113 // Open the master side of a pseudo terminal
114 m_master_fd = ::posix_openpt (oflag);
115 if (m_master_fd < 0)
116 {
117 if (error_str)
118 ::strerror_r (errno, error_str, error_len);
119 return false;
120 }
121
122 // Grant access to the slave pseudo terminal
123 if (::grantpt (m_master_fd) < 0)
124 {
125 if (error_str)
126 ::strerror_r (errno, error_str, error_len);
127 CloseMasterFileDescriptor ();
128 return false;
129 }
130
131 // Clear the lock flag on the slave pseudo terminal
132 if (::unlockpt (m_master_fd) < 0)
133 {
134 if (error_str)
135 ::strerror_r (errno, error_str, error_len);
136 CloseMasterFileDescriptor ();
137 return false;
138 }
139
140 return true;
141}
142
143//----------------------------------------------------------------------
144// Open the slave pseudo terminal for the current master pseudo
145// terminal. A master pseudo terminal should already be valid prior to
146// calling this function (see OpenFirstAvailableMaster()).
147// The file descriptor is stored this object's member variables and can
148// be accessed via the GetSlaveFileDescriptor(), or released using the
149// ReleaseSlaveFileDescriptor() member function.
150//
151// RETURNS:
152// Zero when successful, non-zero indicating an error occurred.
153//----------------------------------------------------------------------
154bool
155PseudoTerminal::OpenSlave (int oflag, char *error_str, size_t error_len)
156{
157 if (error_str)
158 error_str[0] = '\0';
159
160 CloseSlaveFileDescriptor();
161
162 // Open the master side of a pseudo terminal
163 const char *slave_name = GetSlaveName (error_str, error_len);
164
Ed Masted4612ad2014-04-20 13:17:36 +0000165 if (slave_name == nullptr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000166 return false;
167
168 m_slave_fd = ::open (slave_name, oflag);
169
170 if (m_slave_fd < 0)
171 {
172 if (error_str)
173 ::strerror_r (errno, error_str, error_len);
174 return false;
175 }
176
177 return true;
178}
179
180
181
182//----------------------------------------------------------------------
183// Get the name of the slave pseudo terminal. A master pseudo terminal
184// should already be valid prior to calling this function (see
185// OpenFirstAvailableMaster()).
186//
187// RETURNS:
188// NULL if no valid master pseudo terminal or if ptsname() fails.
189// The name of the slave pseudo terminal as a NULL terminated C string
190// that comes from static memory, so a copy of the string should be
191// made as subsequent calls can change this value.
192//----------------------------------------------------------------------
193const char*
194PseudoTerminal::GetSlaveName (char *error_str, size_t error_len) const
195{
196 if (error_str)
197 error_str[0] = '\0';
198
199 if (m_master_fd < 0)
200 {
201 if (error_str)
202 ::snprintf (error_str, error_len, "%s", "master file descriptor is invalid");
Ed Masted4612ad2014-04-20 13:17:36 +0000203 return nullptr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000204 }
205 const char *slave_name = ::ptsname (m_master_fd);
206
Ed Masted4612ad2014-04-20 13:17:36 +0000207 if (error_str && slave_name == nullptr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000208 ::strerror_r (errno, error_str, error_len);
209
210 return slave_name;
211}
212
213
214//----------------------------------------------------------------------
215// Fork a child process and have its stdio routed to a pseudo terminal.
216//
217// In the parent process when a valid pid is returned, the master file
218// descriptor can be used as a read/write access to stdio of the
219// child process.
220//
221// In the child process the stdin/stdout/stderr will already be routed
222// to the slave pseudo terminal and the master file descriptor will be
223// closed as it is no longer needed by the child process.
224//
225// This class will close the file descriptors for the master/slave
226// when the destructor is called, so be sure to call
227// ReleaseMasterFileDescriptor() or ReleaseSlaveFileDescriptor() if any
228// file descriptors are going to be used past the lifespan of this
229// object.
230//
231// RETURNS:
232// in the parent process: the pid of the child, or -1 if fork fails
233// in the child process: zero
234//----------------------------------------------------------------------
235lldb::pid_t
236PseudoTerminal::Fork (char *error_str, size_t error_len)
237{
238 if (error_str)
239 error_str[0] = '\0';
240
241 pid_t pid = LLDB_INVALID_PROCESS_ID;
242 if (OpenFirstAvailableMaster (O_RDWR, error_str, error_len))
243 {
244 // Successfully opened our master pseudo terminal
245
246 pid = ::fork ();
247 if (pid < 0)
248 {
249 // Fork failed
250 if (error_str)
251 ::strerror_r (errno, error_str, error_len);
252 }
253 else if (pid == 0)
254 {
255 // Child Process
256 ::setsid();
257
258 if (OpenSlave (O_RDWR, error_str, error_len))
259 {
260 // Successfully opened slave
261 // We are done with the master in the child process so lets close it
262 CloseMasterFileDescriptor ();
263
Greg Clayton000aeb82011-02-09 17:41:27 +0000264#if defined(TIOCSCTTY)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000265 // Acquire the controlling terminal
266 if (::ioctl (m_slave_fd, TIOCSCTTY, (char *)0) < 0)
267 {
268 if (error_str)
269 ::strerror_r (errno, error_str, error_len);
270 }
271#endif
272 // Duplicate all stdio file descriptors to the slave pseudo terminal
273 if (::dup2 (m_slave_fd, STDIN_FILENO) != STDIN_FILENO)
274 {
275 if (error_str && !error_str[0])
276 ::strerror_r (errno, error_str, error_len);
277 }
278
279 if (::dup2 (m_slave_fd, STDOUT_FILENO) != STDOUT_FILENO)
280 {
281 if (error_str && !error_str[0])
282 ::strerror_r (errno, error_str, error_len);
283 }
284
285 if (::dup2 (m_slave_fd, STDERR_FILENO) != STDERR_FILENO)
286 {
287 if (error_str && !error_str[0])
288 ::strerror_r (errno, error_str, error_len);
289 }
290 }
291 }
292 else
293 {
294 // Parent Process
295 // Do nothing and let the pid get returned!
296 }
297 }
298 return pid;
299}
300
301//----------------------------------------------------------------------
302// The master file descriptor accessor. This object retains ownership
303// of the master file descriptor when this accessor is used. Use
304// ReleaseMasterFileDescriptor() if you wish this object to release
305// ownership of the master file descriptor.
306//
307// Returns the master file descriptor, or -1 if the master file
308// descriptor is not currently valid.
309//----------------------------------------------------------------------
310int
311PseudoTerminal::GetMasterFileDescriptor () const
312{
313 return m_master_fd;
314}
315
316//----------------------------------------------------------------------
317// The slave file descriptor accessor.
318//
319// Returns the slave file descriptor, or -1 if the slave file
320// descriptor is not currently valid.
321//----------------------------------------------------------------------
322int
323PseudoTerminal::GetSlaveFileDescriptor () const
324{
325 return m_slave_fd;
326}
327
328//----------------------------------------------------------------------
329// Release ownership of the master pseudo terminal file descriptor
330// without closing it. The destructor for this class will close the
331// master file descriptor if the ownership isn't released using this
332// call and the master file descriptor has been opened.
333//----------------------------------------------------------------------
334int
335PseudoTerminal::ReleaseMasterFileDescriptor ()
336{
337 // Release ownership of the master pseudo terminal file
338 // descriptor without closing it. (the destructor for this
339 // class will close it otherwise!)
340 int fd = m_master_fd;
341 m_master_fd = invalid_fd;
342 return fd;
343}
344
345//----------------------------------------------------------------------
346// Release ownership of the slave pseudo terminal file descriptor
347// without closing it. The destructor for this class will close the
348// slave file descriptor if the ownership isn't released using this
349// call and the slave file descriptor has been opened.
350//----------------------------------------------------------------------
351int
352PseudoTerminal::ReleaseSlaveFileDescriptor ()
353{
354 // Release ownership of the slave pseudo terminal file
355 // descriptor without closing it (the destructor for this
356 // class will close it otherwise!)
357 int fd = m_slave_fd;
358 m_slave_fd = invalid_fd;
359 return fd;
360}
361