summaryrefslogtreecommitdiff
path: root/include/lldb/Host/PseudoTerminal.h
blob: 858bd35f73a6a35a50fe10711f495051d22f08a8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
//===-- PseudoTerminal.h ----------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#ifndef LLDB_HOST_PSEUDOTERMINAL_H
#define LLDB_HOST_PSEUDOTERMINAL_H

#include <fcntl.h>
#include <string>

#include "lldb/lldb-defines.h"

namespace lldb_private {

//----------------------------------------------------------------------
/// @class PseudoTerminal PseudoTerminal.h "lldb/Host/PseudoTerminal.h"
/// A pseudo terminal helper class.
///
/// The pseudo terminal class abstracts the use of pseudo terminals on the
/// host system.
//----------------------------------------------------------------------
class PseudoTerminal {
public:
  enum {
    invalid_fd = -1 ///< Invalid file descriptor value
  };

  //------------------------------------------------------------------
  /// Default constructor
  ///
  /// Constructs this object with invalid master and slave file descriptors.
  //------------------------------------------------------------------
  PseudoTerminal();

  //------------------------------------------------------------------
  /// Destructor
  ///
  /// The destructor will close the master and slave file descriptors if they
  /// are valid and ownership has not been released using one of: @li
  /// PseudoTerminal::ReleaseMasterFileDescriptor() @li
  /// PseudoTerminal::ReleaseSaveFileDescriptor()
  //------------------------------------------------------------------
  ~PseudoTerminal();

  //------------------------------------------------------------------
  /// Close the master file descriptor if it is valid.
  //------------------------------------------------------------------
  void CloseMasterFileDescriptor();

  //------------------------------------------------------------------
  /// Close the slave file descriptor if it is valid.
  //------------------------------------------------------------------
  void CloseSlaveFileDescriptor();

  //------------------------------------------------------------------
  /// Fork a child process that uses pseudo terminals for its stdio.
  ///
  /// In the parent process, a call to this function results in a pid being
  /// returned. If the pid is valid, the master file descriptor can be used
  /// for read/write access to stdio of the child process.
  ///
  /// In the child process the stdin/stdout/stderr will already be routed to
  /// the slave pseudo terminal and the master file descriptor will be closed
  /// as it is no longer needed by the child process.
  ///
  /// This class will close the file descriptors for the master/slave when the
  /// destructor is called. The file handles can be released using either: @li
  /// PseudoTerminal::ReleaseMasterFileDescriptor() @li
  /// PseudoTerminal::ReleaseSaveFileDescriptor()
  ///
  /// @param[out] error
  ///     An pointer to an error that can describe any errors that
  ///     occur. This can be NULL if no error status is desired.
  ///
  /// @return
  ///     @li \b Parent process: a child process ID that is greater
  ///         than zero, or -1 if the fork fails.
  ///     @li \b Child process: zero.
  //------------------------------------------------------------------
  lldb::pid_t Fork(char *error_str, size_t error_len);

  //------------------------------------------------------------------
  /// The master file descriptor accessor.
  ///
  /// This object retains ownership of the master file descriptor when this
  /// accessor is used. Users can call the member function
  /// PseudoTerminal::ReleaseMasterFileDescriptor() if this object should
  /// release ownership of the slave file descriptor.
  ///
  /// @return
  ///     The master file descriptor, or PseudoTerminal::invalid_fd
  ///     if the master file  descriptor is not currently valid.
  ///
  /// @see PseudoTerminal::ReleaseMasterFileDescriptor()
  //------------------------------------------------------------------
  int GetMasterFileDescriptor() const;

  //------------------------------------------------------------------
  /// The slave file descriptor accessor.
  ///
  /// This object retains ownership of the slave file descriptor when this
  /// accessor is used. Users can call the member function
  /// PseudoTerminal::ReleaseSlaveFileDescriptor() if this object should
  /// release ownership of the slave file descriptor.
  ///
  /// @return
  ///     The slave file descriptor, or PseudoTerminal::invalid_fd
  ///     if the slave file descriptor is not currently valid.
  ///
  /// @see PseudoTerminal::ReleaseSlaveFileDescriptor()
  //------------------------------------------------------------------
  int GetSlaveFileDescriptor() const;

  //------------------------------------------------------------------
  /// Get the name of the slave pseudo terminal.
  ///
  /// A master pseudo terminal should already be valid prior to
  /// calling this function.
  ///
  /// @param[out] error
  ///     An pointer to an error that can describe any errors that
  ///     occur. This can be NULL if no error status is desired.
  ///
  /// @return
  ///     The name of the slave pseudo terminal as a NULL terminated
  ///     C. This string that comes from static memory, so a copy of
  ///     the string should be made as subsequent calls can change
  ///     this value. NULL is returned if this object doesn't have
  ///     a valid master pseudo terminal opened or if the call to
  ///     \c ptsname() fails.
  ///
  /// @see PseudoTerminal::OpenFirstAvailableMaster()
  //------------------------------------------------------------------
  const char *GetSlaveName(char *error_str, size_t error_len) const;

  //------------------------------------------------------------------
  /// Open the first available pseudo terminal.
  ///
  /// Opens the first available pseudo terminal with \a oflag as the
  /// permissions. The opened master file descriptor is stored in this object
  /// and can be accessed by calling the
  /// PseudoTerminal::GetMasterFileDescriptor() accessor. Clients can call the
  /// PseudoTerminal::ReleaseMasterFileDescriptor() accessor function if they
  /// wish to use the master file descriptor beyond the lifespan of this
  /// object.
  ///
  /// If this object still has a valid master file descriptor when its
  /// destructor is called, it will close it.
  ///
  /// @param[in] oflag
  ///     Flags to use when calling \c posix_openpt(\a oflag).
  ///     A value of "O_RDWR|O_NOCTTY" is suggested.
  ///
  /// @param[out] error
  ///     An pointer to an error that can describe any errors that
  ///     occur. This can be NULL if no error status is desired.
  ///
  /// @return
  ///     @li \b true when the master files descriptor is
  ///         successfully opened.
  ///     @li \b false if anything goes wrong.
  ///
  /// @see PseudoTerminal::GetMasterFileDescriptor() @see
  /// PseudoTerminal::ReleaseMasterFileDescriptor()
  //------------------------------------------------------------------
  bool OpenFirstAvailableMaster(int oflag, char *error_str, size_t error_len);

  //------------------------------------------------------------------
  /// Open the slave for the current master pseudo terminal.
  ///
  /// A master pseudo terminal should already be valid prior to
  /// calling this function. The opened slave file descriptor is stored in
  /// this object and can be accessed by calling the
  /// PseudoTerminal::GetSlaveFileDescriptor() accessor. Clients can call the
  /// PseudoTerminal::ReleaseSlaveFileDescriptor() accessor function if they
  /// wish to use the slave file descriptor beyond the lifespan of this
  /// object.
  ///
  /// If this object still has a valid slave file descriptor when its
  /// destructor is called, it will close it.
  ///
  /// @param[in] oflag
  ///     Flags to use when calling \c open(\a oflag).
  ///
  /// @param[out] error
  ///     An pointer to an error that can describe any errors that
  ///     occur. This can be NULL if no error status is desired.
  ///
  /// @return
  ///     @li \b true when the master files descriptor is
  ///         successfully opened.
  ///     @li \b false if anything goes wrong.
  ///
  /// @see PseudoTerminal::OpenFirstAvailableMaster() @see
  /// PseudoTerminal::GetSlaveFileDescriptor() @see
  /// PseudoTerminal::ReleaseSlaveFileDescriptor()
  //------------------------------------------------------------------
  bool OpenSlave(int oflag, char *error_str, size_t error_len);

  //------------------------------------------------------------------
  /// Release the master file descriptor.
  ///
  /// Releases ownership of the master pseudo terminal file descriptor without
  /// closing it. The destructor for this class will close the master file
  /// descriptor if the ownership isn't released using this call and the
  /// master file descriptor has been opened.
  ///
  /// @return
  ///     The master file descriptor, or PseudoTerminal::invalid_fd
  ///     if the mast file descriptor is not currently valid.
  //------------------------------------------------------------------
  int ReleaseMasterFileDescriptor();

  //------------------------------------------------------------------
  /// Release the slave file descriptor.
  ///
  /// Release ownership of the slave pseudo terminal file descriptor without
  /// closing it. The destructor for this class will close the slave file
  /// descriptor if the ownership isn't released using this call and the slave
  /// file descriptor has been opened.
  ///
  /// @return
  ///     The slave file descriptor, or PseudoTerminal::invalid_fd
  ///     if the slave file descriptor is not currently valid.
  //------------------------------------------------------------------
  int ReleaseSlaveFileDescriptor();

protected:
  //------------------------------------------------------------------
  // Member variables
  //------------------------------------------------------------------
  int m_master_fd; ///< The file descriptor for the master.
  int m_slave_fd;  ///< The file descriptor for the slave.

private:
  DISALLOW_COPY_AND_ASSIGN(PseudoTerminal);
};

} // namespace lldb_private

#endif // #ifndef liblldb_PseudoTerminal_h_