1//===-- PseudoTerminal.h ----------------------------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef LLDB_HOST_PSEUDOTERMINAL_H
10#define LLDB_HOST_PSEUDOTERMINAL_H
11
12#include "lldb/lldb-defines.h"
13#include "llvm/Support/Error.h"
14#include <fcntl.h>
15#include <string>
16
17namespace lldb_private {
18
19/// \class PseudoTerminal PseudoTerminal.h "lldb/Host/PseudoTerminal.h"
20/// A pseudo terminal helper class.
21///
22/// The pseudo terminal class abstracts the use of pseudo terminals on the
23/// host system.
24class PseudoTerminal {
25public:
26 enum {
27 invalid_fd = -1 ///< Invalid file descriptor value
28 };
29
30 /// Default constructor
31 ///
32 /// Constructs this object with invalid primary and secondary file
33 /// descriptors.
34 PseudoTerminal();
35
36 /// Destructor
37 ///
38 /// The destructor will close the primary and secondary file descriptors if
39 /// they are valid and ownership has not been released using one of: @li
40 /// PseudoTerminal::ReleasePrimaryFileDescriptor() @li
41 /// PseudoTerminal::ReleaseSaveFileDescriptor()
42 ~PseudoTerminal();
43
44 /// Close the primary file descriptor if it is valid.
45 void ClosePrimaryFileDescriptor();
46
47 /// Close the secondary file descriptor if it is valid.
48 void CloseSecondaryFileDescriptor();
49
50 /// Fork a child process that uses pseudo terminals for its stdio.
51 ///
52 /// In the parent process, a call to this function results in a pid being
53 /// returned. If the pid is valid, the primary file descriptor can be used
54 /// for read/write access to stdio of the child process.
55 ///
56 /// In the child process the stdin/stdout/stderr will already be routed to
57 /// the secondary pseudo terminal and the primary file descriptor will be
58 /// closed as it is no longer needed by the child process.
59 ///
60 /// This class will close the file descriptors for the primary/secondary when
61 /// the destructor is called. The file handles can be released using either:
62 /// @li PseudoTerminal::ReleasePrimaryFileDescriptor() @li
63 /// PseudoTerminal::ReleaseSaveFileDescriptor()
64 ///
65 /// \return
66 /// \b Parent process: a child process ID that is greater
67 /// than zero, or an error if the fork fails.
68 /// \b Child process: zero.
69 llvm::Expected<lldb::pid_t> Fork();
70
71 /// The primary file descriptor accessor.
72 ///
73 /// This object retains ownership of the primary file descriptor when this
74 /// accessor is used. Users can call the member function
75 /// PseudoTerminal::ReleasePrimaryFileDescriptor() if this object should
76 /// release ownership of the secondary file descriptor.
77 ///
78 /// \return
79 /// The primary file descriptor, or PseudoTerminal::invalid_fd
80 /// if the primary file descriptor is not currently valid.
81 ///
82 /// \see PseudoTerminal::ReleasePrimaryFileDescriptor()
83 int GetPrimaryFileDescriptor() const;
84
85 /// The secondary file descriptor accessor.
86 ///
87 /// This object retains ownership of the secondary file descriptor when this
88 /// accessor is used. Users can call the member function
89 /// PseudoTerminal::ReleaseSecondaryFileDescriptor() if this object should
90 /// release ownership of the secondary file descriptor.
91 ///
92 /// \return
93 /// The secondary file descriptor, or PseudoTerminal::invalid_fd
94 /// if the secondary file descriptor is not currently valid.
95 ///
96 /// \see PseudoTerminal::ReleaseSecondaryFileDescriptor()
97 int GetSecondaryFileDescriptor() const;
98
99 /// Get the name of the secondary pseudo terminal.
100 ///
101 /// A primary pseudo terminal should already be valid prior to
102 /// calling this function.
103 ///
104 /// \return
105 /// The name of the secondary pseudo terminal.
106 ///
107 /// \see PseudoTerminal::OpenFirstAvailablePrimary()
108 std::string GetSecondaryName() const;
109
110 /// Open the first available pseudo terminal.
111 ///
112 /// Opens the first available pseudo terminal with \a oflag as the
113 /// permissions. The opened primary file descriptor is stored in this object
114 /// and can be accessed by calling the
115 /// PseudoTerminal::GetPrimaryFileDescriptor() accessor. Clients can call the
116 /// PseudoTerminal::ReleasePrimaryFileDescriptor() accessor function if they
117 /// wish to use the primary file descriptor beyond the lifespan of this
118 /// object.
119 ///
120 /// If this object still has a valid primary file descriptor when its
121 /// destructor is called, it will close it.
122 ///
123 /// \param[in] oflag
124 /// Flags to use when calling \c posix_openpt(\a oflag).
125 /// A value of "O_RDWR|O_NOCTTY" is suggested.
126 ///
127 /// \see PseudoTerminal::GetPrimaryFileDescriptor() @see
128 /// PseudoTerminal::ReleasePrimaryFileDescriptor()
129 llvm::Error OpenFirstAvailablePrimary(int oflag);
130
131 /// Open the secondary for the current primary pseudo terminal.
132 ///
133 /// A primary pseudo terminal should already be valid prior to
134 /// calling this function. The opened secondary file descriptor is stored in
135 /// this object and can be accessed by calling the
136 /// PseudoTerminal::GetSecondaryFileDescriptor() accessor. Clients can call
137 /// the PseudoTerminal::ReleaseSecondaryFileDescriptor() accessor function if
138 /// they wish to use the secondary file descriptor beyond the lifespan of this
139 /// object.
140 ///
141 /// If this object still has a valid secondary file descriptor when its
142 /// destructor is called, it will close it.
143 ///
144 /// \param[in] oflag
145 /// Flags to use when calling \c open(\a oflag).
146 ///
147 /// \see PseudoTerminal::OpenFirstAvailablePrimary() @see
148 /// PseudoTerminal::GetSecondaryFileDescriptor() @see
149 /// PseudoTerminal::ReleaseSecondaryFileDescriptor()
150 llvm::Error OpenSecondary(int oflag);
151
152 /// Release the primary file descriptor.
153 ///
154 /// Releases ownership of the primary pseudo terminal file descriptor without
155 /// closing it. The destructor for this class will close the primary file
156 /// descriptor if the ownership isn't released using this call and the
157 /// primary file descriptor has been opened.
158 ///
159 /// \return
160 /// The primary file descriptor, or PseudoTerminal::invalid_fd
161 /// if the mast file descriptor is not currently valid.
162 int ReleasePrimaryFileDescriptor();
163
164 /// Release the secondary file descriptor.
165 ///
166 /// Release ownership of the secondary pseudo terminal file descriptor without
167 /// closing it. The destructor for this class will close the secondary file
168 /// descriptor if the ownership isn't released using this call and the
169 /// secondary file descriptor has been opened.
170 ///
171 /// \return
172 /// The secondary file descriptor, or PseudoTerminal::invalid_fd
173 /// if the secondary file descriptor is not currently valid.
174 int ReleaseSecondaryFileDescriptor();
175
176protected:
177 // Member variables
178 int m_primary_fd = invalid_fd; ///< The file descriptor for the primary.
179 int m_secondary_fd = invalid_fd; ///< The file descriptor for the secondary.
180
181private:
182 PseudoTerminal(const PseudoTerminal &) = delete;
183 const PseudoTerminal &operator=(const PseudoTerminal &) = delete;
184};
185
186} // namespace lldb_private
187
188#endif // LLDB_HOST_PSEUDOTERMINAL_H
189

source code of lldb/include/lldb/Host/PseudoTerminal.h