//===-- PseudoTerminal.h ----------------------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #ifndef LLDB_HOST_PSEUDOTERMINAL_H #define LLDB_HOST_PSEUDOTERMINAL_H #include #include #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_