blob: e728d4ab2a984c62be76d8a8116db7fbdb386419 [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
Zachary Turner49be1602015-02-25 19:52:41 +0000241 pid_t pid = LLDB_INVALID_PROCESS_ID;
Zachary Turnerbf0f2b92015-02-09 19:13:46 +0000242 int flags = O_RDWR;
Zachary Turner49be1602015-02-25 19:52:41 +0000243#if !defined(_MSC_VER)
Zachary Turnerbf0f2b92015-02-09 19:13:46 +0000244 flags |= O_CLOEXEC;
Zachary Turner49be1602015-02-25 19:52:41 +0000245#endif
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 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000303 return pid;
304}
305
306//----------------------------------------------------------------------
307// The master file descriptor accessor. This object retains ownership
308// of the master file descriptor when this accessor is used. Use
309// ReleaseMasterFileDescriptor() if you wish this object to release
310// ownership of the master file descriptor.
311//
312// Returns the master file descriptor, or -1 if the master file
313// descriptor is not currently valid.
314//----------------------------------------------------------------------
315int
316PseudoTerminal::GetMasterFileDescriptor () const
317{
318 return m_master_fd;
319}
320
321//----------------------------------------------------------------------
322// The slave file descriptor accessor.
323//
324// Returns the slave file descriptor, or -1 if the slave file
325// descriptor is not currently valid.
326//----------------------------------------------------------------------
327int
328PseudoTerminal::GetSlaveFileDescriptor () const
329{
330 return m_slave_fd;
331}
332
333//----------------------------------------------------------------------
334// Release ownership of the master pseudo terminal file descriptor
335// without closing it. The destructor for this class will close the
336// master file descriptor if the ownership isn't released using this
337// call and the master file descriptor has been opened.
338//----------------------------------------------------------------------
339int
340PseudoTerminal::ReleaseMasterFileDescriptor ()
341{
342 // Release ownership of the master pseudo terminal file
343 // descriptor without closing it. (the destructor for this
344 // class will close it otherwise!)
345 int fd = m_master_fd;
346 m_master_fd = invalid_fd;
347 return fd;
348}
349
350//----------------------------------------------------------------------
351// Release ownership of the slave pseudo terminal file descriptor
352// without closing it. The destructor for this class will close the
353// slave file descriptor if the ownership isn't released using this
354// call and the slave file descriptor has been opened.
355//----------------------------------------------------------------------
356int
357PseudoTerminal::ReleaseSlaveFileDescriptor ()
358{
359 // Release ownership of the slave pseudo terminal file
360 // descriptor without closing it (the destructor for this
361 // class will close it otherwise!)
362 int fd = m_slave_fd;
363 m_slave_fd = invalid_fd;
364 return fd;
365}
366