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 17 namespace 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. 24 class PseudoTerminal { 25 public: 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 176 protected: 177 // Member variables 178 int m_primary_fd; ///< The file descriptor for the primary. 179 int m_secondary_fd; ///< The file descriptor for the secondary. 180 181 private: 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