PseudoTerminal.h 7.1 KB

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