blob: bc3cfee226f885cd06cb284de4455cc78e845dfb [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
Zachary Turner48b475c2015-04-02 20:57:38 +000010#include "lldb/Host/Config.h"
Jason Molendaa34a0c62010-06-09 21:28:42 +000011#include "lldb/Utility/PseudoTerminal.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000012
13#include <errno.h>
14#include <stdlib.h>
15#include <string.h>
Eli Friedmanf254f8b2010-06-09 09:38:08 +000016#include <stdio.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
Virgile Bellob2f1fb22013-08-23 12:44:05 +000021#ifdef _WIN32
22#include "lldb/Host/windows/win32.h"
Deepak Panickal9b35cf52014-07-01 17:57:19 +000023typedef uint32_t pid_t;
Virgile Bellob2f1fb22013-08-23 12:44:05 +000024// empty functions
25int posix_openpt(int flag) { return 0; }
26
27int strerror_r(int errnum, char *buf, size_t buflen) { return 0; }
28
29int unlockpt(int fd) { return 0; }
30int grantpt(int fd) { return 0; }
31char *ptsname(int fd) { return 0; }
32
33pid_t fork(void) { return 0; }
34pid_t setsid(void) { return 0; }
Shawn Best8da0bf32014-11-08 01:41:49 +000035#elif defined(__ANDROID_NDK__)
36#include "lldb/Host/android/Android.h"
Vince Harron8b335672015-05-12 01:10:56 +000037int posix_openpt(int flags);
Virgile Bellob2f1fb22013-08-23 12:44:05 +000038#endif
39
Chris Lattner30fdc8d2010-06-08 16:52:24 +000040using namespace lldb_utility;
41
42//----------------------------------------------------------------------
43// PseudoTerminal constructor
44//----------------------------------------------------------------------
45PseudoTerminal::PseudoTerminal () :
46 m_master_fd(invalid_fd),
47 m_slave_fd(invalid_fd)
48{
49}
50
51//----------------------------------------------------------------------
52// Destructor
53//
54// The destructor will close the master and slave file descriptors
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +000055// if they are valid and ownership has not been released using the
Chris Lattner30fdc8d2010-06-08 16:52:24 +000056// ReleaseMasterFileDescriptor() or the ReleaseSaveFileDescriptor()
57// member functions.
58//----------------------------------------------------------------------
59PseudoTerminal::~PseudoTerminal ()
60{
61 CloseMasterFileDescriptor();
62 CloseSlaveFileDescriptor();
63}
64
65//----------------------------------------------------------------------
66// Close the master file descriptor if it is valid.
67//----------------------------------------------------------------------
68void
69PseudoTerminal::CloseMasterFileDescriptor ()
70{
71 if (m_master_fd >= 0)
72 {
Hafiz Abid Qadeerf2896282014-10-27 19:27:00 +000073 // 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.
75#ifndef _WIN32
Chris Lattner30fdc8d2010-06-08 16:52:24 +000076 ::close (m_master_fd);
Hafiz Abid Qadeerf2896282014-10-27 19:27:00 +000077#endif
Chris Lattner30fdc8d2010-06-08 16:52:24 +000078 m_master_fd = invalid_fd;
79 }
80}
81
82//----------------------------------------------------------------------
83// Close the slave file descriptor if it is valid.
84//----------------------------------------------------------------------
85void
86PseudoTerminal::CloseSlaveFileDescriptor ()
87{
88 if (m_slave_fd >= 0)
89 {
90 ::close (m_slave_fd);
91 m_slave_fd = invalid_fd;
92 }
93}
94
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.
105//
106// RETURNS:
107// Zero when successful, non-zero indicating an error occurred.
108//----------------------------------------------------------------------
109bool
110PseudoTerminal::OpenFirstAvailableMaster (int oflag, char *error_str, size_t error_len)
111{
112 if (error_str)
113 error_str[0] = '\0';
114
115 // Open the master side of a pseudo terminal
116 m_master_fd = ::posix_openpt (oflag);
117 if (m_master_fd < 0)
118 {
119 if (error_str)
120 ::strerror_r (errno, error_str, error_len);
121 return false;
122 }
123
124 // Grant access to the slave pseudo terminal
125 if (::grantpt (m_master_fd) < 0)
126 {
127 if (error_str)
128 ::strerror_r (errno, error_str, error_len);
129 CloseMasterFileDescriptor ();
130 return false;
131 }
132
133 // Clear the lock flag on the slave pseudo terminal
134 if (::unlockpt (m_master_fd) < 0)
135 {
136 if (error_str)
137 ::strerror_r (errno, error_str, error_len);
138 CloseMasterFileDescriptor ();
139 return false;
140 }
141
142 return true;
143}
144
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.
152//
153// RETURNS:
154// Zero when successful, non-zero indicating an error occurred.
155//----------------------------------------------------------------------
156bool
157PseudoTerminal::OpenSlave (int oflag, char *error_str, size_t error_len)
158{
159 if (error_str)
160 error_str[0] = '\0';
161
162 CloseSlaveFileDescriptor();
163
164 // Open the master side of a pseudo terminal
165 const char *slave_name = GetSlaveName (error_str, error_len);
166
Ed Masted4612ad2014-04-20 13:17:36 +0000167 if (slave_name == nullptr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000168 return false;
169
170 m_slave_fd = ::open (slave_name, oflag);
171
172 if (m_slave_fd < 0)
173 {
174 if (error_str)
175 ::strerror_r (errno, error_str, error_len);
176 return false;
177 }
178
179 return true;
180}
181
182
183
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()).
188//
189// RETURNS:
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//----------------------------------------------------------------------
195const char*
196PseudoTerminal::GetSlaveName (char *error_str, size_t error_len) const
197{
198 if (error_str)
199 error_str[0] = '\0';
200
201 if (m_master_fd < 0)
202 {
203 if (error_str)
204 ::snprintf (error_str, error_len, "%s", "master file descriptor is invalid");
Ed Masted4612ad2014-04-20 13:17:36 +0000205 return nullptr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000206 }
207 const char *slave_name = ::ptsname (m_master_fd);
208
Ed Masted4612ad2014-04-20 13:17:36 +0000209 if (error_str && slave_name == nullptr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000210 ::strerror_r (errno, error_str, error_len);
211
212 return slave_name;
213}
214
215
216//----------------------------------------------------------------------
217// Fork a child process and have its stdio routed to a pseudo terminal.
218//
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
221// child process.
222//
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.
226//
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
231// object.
232//
233// RETURNS:
234// in the parent process: the pid of the child, or -1 if fork fails
235// in the child process: zero
236//----------------------------------------------------------------------
237lldb::pid_t
238PseudoTerminal::Fork (char *error_str, size_t error_len)
239{
240 if (error_str)
241 error_str[0] = '\0';
Zachary Turner49be1602015-02-25 19:52:41 +0000242 pid_t pid = LLDB_INVALID_PROCESS_ID;
Zachary Turner48b475c2015-04-02 20:57:38 +0000243#if !defined(LLDB_DISABLE_POSIX)
Zachary Turnerbf0f2b92015-02-09 19:13:46 +0000244 int flags = O_RDWR;
Zachary Turnerbf0f2b92015-02-09 19:13:46 +0000245 flags |= O_CLOEXEC;
Zachary Turnerbf0f2b92015-02-09 19:13:46 +0000246 if (OpenFirstAvailableMaster (flags, error_str, error_len))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000247 {
248 // Successfully opened our master pseudo terminal
249
250 pid = ::fork ();
251 if (pid < 0)
252 {
253 // Fork failed
254 if (error_str)
255 ::strerror_r (errno, error_str, error_len);
256 }
257 else if (pid == 0)
258 {
259 // Child Process
260 ::setsid();
261
262 if (OpenSlave (O_RDWR, error_str, error_len))
263 {
264 // Successfully opened slave
Pavel Labathb4bf1c62015-02-09 11:37:56 +0000265
266 // Master FD should have O_CLOEXEC set, but let's close it just in case...
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000267 CloseMasterFileDescriptor ();
268
Greg Clayton000aeb82011-02-09 17:41:27 +0000269#if defined(TIOCSCTTY)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000270 // Acquire the controlling terminal
271 if (::ioctl (m_slave_fd, TIOCSCTTY, (char *)0) < 0)
272 {
273 if (error_str)
274 ::strerror_r (errno, error_str, error_len);
275 }
276#endif
277 // Duplicate all stdio file descriptors to the slave pseudo terminal
278 if (::dup2 (m_slave_fd, STDIN_FILENO) != STDIN_FILENO)
279 {
280 if (error_str && !error_str[0])
281 ::strerror_r (errno, error_str, error_len);
282 }
283
284 if (::dup2 (m_slave_fd, STDOUT_FILENO) != STDOUT_FILENO)
285 {
286 if (error_str && !error_str[0])
287 ::strerror_r (errno, error_str, error_len);
288 }
289
290 if (::dup2 (m_slave_fd, STDERR_FILENO) != STDERR_FILENO)
291 {
292 if (error_str && !error_str[0])
293 ::strerror_r (errno, error_str, error_len);
294 }
295 }
296 }
297 else
298 {
299 // Parent Process
300 // Do nothing and let the pid get returned!
301 }
302 }
Zachary Turner48b475c2015-04-02 20:57:38 +0000303#endif
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000304 return pid;
305}
306
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.
312//
313// Returns the master file descriptor, or -1 if the master file
314// descriptor is not currently valid.
315//----------------------------------------------------------------------
316int
317PseudoTerminal::GetMasterFileDescriptor () const
318{
319 return m_master_fd;
320}
321
322//----------------------------------------------------------------------
323// The slave file descriptor accessor.
324//
325// Returns the slave file descriptor, or -1 if the slave file
326// descriptor is not currently valid.
327//----------------------------------------------------------------------
328int
329PseudoTerminal::GetSlaveFileDescriptor () const
330{
331 return m_slave_fd;
332}
333
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//----------------------------------------------------------------------
340int
341PseudoTerminal::ReleaseMasterFileDescriptor ()
342{
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;
348 return fd;
349}
350
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//----------------------------------------------------------------------
357int
358PseudoTerminal::ReleaseSlaveFileDescriptor ()
359{
360 // Release ownership of the slave pseudo terminal file
361 // descriptor without closing it (the destructor for this
362 // class will close it otherwise!)
363 int fd = m_slave_fd;
364 m_slave_fd = invalid_fd;
365 return fd;
366}
367