[lldb] Rename Master/Slave to Primary/Secondary (NFC)

This commit is contained in:
Jonas Devlieghere 2020-06-15 15:36:14 -07:00
parent 8c6c49f293
commit 64ec505dd4
20 changed files with 261 additions and 253 deletions

View File

@ -29,36 +29,37 @@ public:
/// Default constructor
///
/// Constructs this object with invalid master and slave file descriptors.
/// Constructs this object with invalid primary and secondary 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
/// The destructor will close the primary and secondary file descriptors if
/// they are valid and ownership has not been released using one of: @li
/// PseudoTerminal::ReleasePrimaryFileDescriptor() @li
/// PseudoTerminal::ReleaseSaveFileDescriptor()
~PseudoTerminal();
/// Close the master file descriptor if it is valid.
void CloseMasterFileDescriptor();
/// Close the primary file descriptor if it is valid.
void ClosePrimaryFileDescriptor();
/// Close the slave file descriptor if it is valid.
void CloseSlaveFileDescriptor();
/// Close the secondary file descriptor if it is valid.
void CloseSecondaryFileDescriptor();
/// 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
/// returned. If the pid is valid, the primary 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.
/// the secondary pseudo terminal and the primary 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
/// This class will close the file descriptors for the primary/secondary when
/// the destructor is called. The file handles can be released using either:
/// @li PseudoTerminal::ReleasePrimaryFileDescriptor() @li
/// PseudoTerminal::ReleaseSaveFileDescriptor()
///
/// \param[out] error_str
@ -71,37 +72,37 @@ public:
/// \b Child process: zero.
lldb::pid_t Fork(char *error_str, size_t error_len);
/// The master file descriptor accessor.
/// The primary file descriptor accessor.
///
/// This object retains ownership of the master file descriptor when this
/// This object retains ownership of the primary 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.
/// PseudoTerminal::ReleasePrimaryFileDescriptor() if this object should
/// release ownership of the secondary file descriptor.
///
/// \return
/// The master file descriptor, or PseudoTerminal::invalid_fd
/// if the master file descriptor is not currently valid.
/// The primary file descriptor, or PseudoTerminal::invalid_fd
/// if the primary file descriptor is not currently valid.
///
/// \see PseudoTerminal::ReleaseMasterFileDescriptor()
int GetMasterFileDescriptor() const;
/// \see PseudoTerminal::ReleasePrimaryFileDescriptor()
int GetPrimaryFileDescriptor() const;
/// The slave file descriptor accessor.
/// The secondary file descriptor accessor.
///
/// This object retains ownership of the slave file descriptor when this
/// This object retains ownership of the secondary 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.
/// PseudoTerminal::ReleaseSecondaryFileDescriptor() if this object should
/// release ownership of the secondary file descriptor.
///
/// \return
/// The slave file descriptor, or PseudoTerminal::invalid_fd
/// if the slave file descriptor is not currently valid.
/// The secondary file descriptor, or PseudoTerminal::invalid_fd
/// if the secondary file descriptor is not currently valid.
///
/// \see PseudoTerminal::ReleaseSlaveFileDescriptor()
int GetSlaveFileDescriptor() const;
/// \see PseudoTerminal::ReleaseSecondaryFileDescriptor()
int GetSecondaryFileDescriptor() const;
/// Get the name of the slave pseudo terminal.
/// Get the name of the secondary pseudo terminal.
///
/// A master pseudo terminal should already be valid prior to
/// A primary pseudo terminal should already be valid prior to
/// calling this function.
///
/// \param[out] error_str
@ -109,27 +110,27 @@ public:
/// occur. This can be NULL if no error status is desired.
///
/// \return
/// The name of the slave pseudo terminal as a NULL terminated
/// The name of the secondary 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
/// a valid primary 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;
/// \see PseudoTerminal::OpenFirstAvailablePrimary()
const char *GetSecondaryName(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
/// permissions. The opened primary 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
/// PseudoTerminal::GetPrimaryFileDescriptor() accessor. Clients can call the
/// PseudoTerminal::ReleasePrimaryFileDescriptor() accessor function if they
/// wish to use the primary file descriptor beyond the lifespan of this
/// object.
///
/// If this object still has a valid master file descriptor when its
/// If this object still has a valid primary file descriptor when its
/// destructor is called, it will close it.
///
/// \param[in] oflag
@ -141,25 +142,25 @@ public:
/// occur. This can be NULL if no error status is desired.
///
/// \return
/// \b true when the master files descriptor is
/// \b true when the primary files descriptor is
/// successfully opened.
/// \b false if anything goes wrong.
///
/// \see PseudoTerminal::GetMasterFileDescriptor() @see
/// PseudoTerminal::ReleaseMasterFileDescriptor()
bool OpenFirstAvailableMaster(int oflag, char *error_str, size_t error_len);
/// \see PseudoTerminal::GetPrimaryFileDescriptor() @see
/// PseudoTerminal::ReleasePrimaryFileDescriptor()
bool OpenFirstAvailablePrimary(int oflag, char *error_str, size_t error_len);
/// Open the slave for the current master pseudo terminal.
/// Open the secondary for the current primary pseudo terminal.
///
/// A master pseudo terminal should already be valid prior to
/// calling this function. The opened slave file descriptor is stored in
/// A primary pseudo terminal should already be valid prior to
/// calling this function. The opened secondary 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
/// PseudoTerminal::GetSecondaryFileDescriptor() accessor. Clients can call
/// the PseudoTerminal::ReleaseSecondaryFileDescriptor() accessor function if
/// they wish to use the secondary file descriptor beyond the lifespan of this
/// object.
///
/// If this object still has a valid slave file descriptor when its
/// If this object still has a valid secondary file descriptor when its
/// destructor is called, it will close it.
///
/// \param[in] oflag
@ -170,43 +171,43 @@ public:
/// occur. This can be NULL if no error status is desired.
///
/// \return
/// \b true when the master files descriptor is
/// \b true when the primary files descriptor is
/// successfully opened.
/// \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);
/// \see PseudoTerminal::OpenFirstAvailablePrimary() @see
/// PseudoTerminal::GetSecondaryFileDescriptor() @see
/// PseudoTerminal::ReleaseSecondaryFileDescriptor()
bool OpenSecondary(int oflag, char *error_str, size_t error_len);
/// Release the master file descriptor.
/// Release the primary file descriptor.
///
/// Releases ownership of the master pseudo terminal file descriptor without
/// closing it. The destructor for this class will close the master file
/// Releases ownership of the primary pseudo terminal file descriptor without
/// closing it. The destructor for this class will close the primary file
/// descriptor if the ownership isn't released using this call and the
/// master file descriptor has been opened.
/// primary file descriptor has been opened.
///
/// \return
/// The master file descriptor, or PseudoTerminal::invalid_fd
/// The primary file descriptor, or PseudoTerminal::invalid_fd
/// if the mast file descriptor is not currently valid.
int ReleaseMasterFileDescriptor();
int ReleasePrimaryFileDescriptor();
/// Release the slave file descriptor.
/// Release the secondary 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.
/// Release ownership of the secondary pseudo terminal file descriptor without
/// closing it. The destructor for this class will close the secondary file
/// descriptor if the ownership isn't released using this call and the
/// secondary 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();
/// The secondary file descriptor, or PseudoTerminal::invalid_fd
/// if the secondary file descriptor is not currently valid.
int ReleaseSecondaryFileDescriptor();
protected:
// Member variables
int m_master_fd; ///< The file descriptor for the master.
int m_slave_fd; ///< The file descriptor for the slave.
int m_primary_fd; ///< The file descriptor for the primary.
int m_secondary_fd; ///< The file descriptor for the secondary.
private:
PseudoTerminal(const PseudoTerminal &) = delete;

View File

@ -469,8 +469,6 @@ public:
const char *GetScriptInterpreterPtyName();
int GetMasterFileDescriptor();
virtual llvm::Expected<unsigned>
GetMaxPositionalArgumentsForCallable(const llvm::StringRef &callable_name) {
return llvm::createStringError(

View File

@ -218,26 +218,26 @@ llvm::Error ProcessLaunchInfo::SetUpPtyRedirection() {
// do for now.
open_flags |= O_CLOEXEC;
#endif
if (!m_pty->OpenFirstAvailableMaster(open_flags, nullptr, 0)) {
if (!m_pty->OpenFirstAvailablePrimary(open_flags, nullptr, 0)) {
return llvm::createStringError(llvm::inconvertibleErrorCode(),
"PTY::OpenFirstAvailableMaster failed");
"PTY::OpenFirstAvailablePrimary failed");
}
const FileSpec slave_file_spec(m_pty->GetSlaveName(nullptr, 0));
const FileSpec secondary_file_spec(m_pty->GetSecondaryName(nullptr, 0));
// Only use the slave tty if we don't have anything specified for
// Only use the secondary tty if we don't have anything specified for
// input and don't have an action for stdin
if (GetFileActionForFD(STDIN_FILENO) == nullptr)
AppendOpenFileAction(STDIN_FILENO, slave_file_spec, true, false);
AppendOpenFileAction(STDIN_FILENO, secondary_file_spec, true, false);
// Only use the slave tty if we don't have anything specified for
// Only use the secondary tty if we don't have anything specified for
// output and don't have an action for stdout
if (GetFileActionForFD(STDOUT_FILENO) == nullptr)
AppendOpenFileAction(STDOUT_FILENO, slave_file_spec, false, true);
AppendOpenFileAction(STDOUT_FILENO, secondary_file_spec, false, true);
// Only use the slave tty if we don't have anything specified for
// Only use the secondary tty if we don't have anything specified for
// error and don't have an action for stderr
if (GetFileActionForFD(STDERR_FILENO) == nullptr)
AppendOpenFileAction(STDERR_FILENO, slave_file_spec, false, true);
AppendOpenFileAction(STDERR_FILENO, secondary_file_spec, false, true);
return llvm::Error::success();
}

View File

@ -34,73 +34,73 @@ static void ErrnoToStr(char *error_str, size_t error_len) {
// PseudoTerminal constructor
PseudoTerminal::PseudoTerminal()
: m_master_fd(invalid_fd), m_slave_fd(invalid_fd) {}
: m_primary_fd(invalid_fd), m_secondary_fd(invalid_fd) {}
// Destructor
//
// The destructor will close the master and slave file descriptors if they are
// valid and ownership has not been released using the
// ReleaseMasterFileDescriptor() or the ReleaseSaveFileDescriptor() member
// The destructor will close the primary and secondary file descriptors if they
// are valid and ownership has not been released using the
// ReleasePrimaryFileDescriptor() or the ReleaseSaveFileDescriptor() member
// functions.
PseudoTerminal::~PseudoTerminal() {
CloseMasterFileDescriptor();
CloseSlaveFileDescriptor();
ClosePrimaryFileDescriptor();
CloseSecondaryFileDescriptor();
}
// Close the master file descriptor if it is valid.
void PseudoTerminal::CloseMasterFileDescriptor() {
if (m_master_fd >= 0) {
::close(m_master_fd);
m_master_fd = invalid_fd;
// Close the primary file descriptor if it is valid.
void PseudoTerminal::ClosePrimaryFileDescriptor() {
if (m_primary_fd >= 0) {
::close(m_primary_fd);
m_primary_fd = invalid_fd;
}
}
// Close the slave file descriptor if it is valid.
void PseudoTerminal::CloseSlaveFileDescriptor() {
if (m_slave_fd >= 0) {
::close(m_slave_fd);
m_slave_fd = invalid_fd;
// Close the secondary file descriptor if it is valid.
void PseudoTerminal::CloseSecondaryFileDescriptor() {
if (m_secondary_fd >= 0) {
::close(m_secondary_fd);
m_secondary_fd = invalid_fd;
}
}
// Open the first available pseudo terminal with OFLAG as the permissions. The
// file descriptor is stored in this object and can be accessed with the
// MasterFileDescriptor() accessor. The ownership of the master file descriptor
// can be released using the ReleaseMasterFileDescriptor() accessor. If this
// object has a valid master files descriptor when its destructor is called, it
// will close the master file descriptor, therefore clients must call
// ReleaseMasterFileDescriptor() if they wish to use the master file descriptor
// after this object is out of scope or destroyed.
// PrimaryFileDescriptor() accessor. The ownership of the primary file
// descriptor can be released using the ReleasePrimaryFileDescriptor() accessor.
// If this object has a valid primary files descriptor when its destructor is
// called, it will close the primary file descriptor, therefore clients must
// call ReleasePrimaryFileDescriptor() if they wish to use the primary file
// descriptor after this object is out of scope or destroyed.
//
// RETURNS:
// True when successful, false indicating an error occurred.
bool PseudoTerminal::OpenFirstAvailableMaster(int oflag, char *error_str,
size_t error_len) {
bool PseudoTerminal::OpenFirstAvailablePrimary(int oflag, char *error_str,
size_t error_len) {
if (error_str)
error_str[0] = '\0';
#if LLDB_ENABLE_POSIX
// Open the master side of a pseudo terminal
m_master_fd = ::posix_openpt(oflag);
if (m_master_fd < 0) {
// Open the primary side of a pseudo terminal
m_primary_fd = ::posix_openpt(oflag);
if (m_primary_fd < 0) {
if (error_str)
ErrnoToStr(error_str, error_len);
return false;
}
// Grant access to the slave pseudo terminal
if (::grantpt(m_master_fd) < 0) {
// Grant access to the secondary pseudo terminal
if (::grantpt(m_primary_fd) < 0) {
if (error_str)
ErrnoToStr(error_str, error_len);
CloseMasterFileDescriptor();
ClosePrimaryFileDescriptor();
return false;
}
// Clear the lock flag on the slave pseudo terminal
if (::unlockpt(m_master_fd) < 0) {
// Clear the lock flag on the secondary pseudo terminal
if (::unlockpt(m_primary_fd) < 0) {
if (error_str)
ErrnoToStr(error_str, error_len);
CloseMasterFileDescriptor();
ClosePrimaryFileDescriptor();
return false;
}
@ -112,30 +112,32 @@ bool PseudoTerminal::OpenFirstAvailableMaster(int oflag, char *error_str,
#endif
}
// Open the slave pseudo terminal for the current master pseudo terminal. A
// master pseudo terminal should already be valid prior to calling this
// function (see OpenFirstAvailableMaster()). The file descriptor is stored
// Open the secondary pseudo terminal for the current primary pseudo terminal. A
// primary pseudo terminal should already be valid prior to calling this
// function (see OpenFirstAvailablePrimary()). The file descriptor is stored
// this object's member variables and can be accessed via the
// GetSlaveFileDescriptor(), or released using the ReleaseSlaveFileDescriptor()
// member function.
// GetSecondaryFileDescriptor(), or released using the
// ReleaseSecondaryFileDescriptor() member function.
//
// RETURNS:
// True when successful, false indicating an error occurred.
bool PseudoTerminal::OpenSlave(int oflag, char *error_str, size_t error_len) {
bool PseudoTerminal::OpenSecondary(int oflag, char *error_str,
size_t error_len) {
if (error_str)
error_str[0] = '\0';
CloseSlaveFileDescriptor();
CloseSecondaryFileDescriptor();
// Open the master side of a pseudo terminal
const char *slave_name = GetSlaveName(error_str, error_len);
// Open the primary side of a pseudo terminal
const char *secondary_name = GetSecondaryName(error_str, error_len);
if (slave_name == nullptr)
if (secondary_name == nullptr)
return false;
m_slave_fd = llvm::sys::RetryAfterSignal(-1, ::open, slave_name, oflag);
m_secondary_fd =
llvm::sys::RetryAfterSignal(-1, ::open, secondary_name, oflag);
if (m_slave_fd < 0) {
if (m_secondary_fd < 0) {
if (error_str)
ErrnoToStr(error_str, error_len);
return false;
@ -144,46 +146,46 @@ bool PseudoTerminal::OpenSlave(int oflag, char *error_str, size_t error_len) {
return true;
}
// Get the name of the slave pseudo terminal. A master pseudo terminal should
// already be valid prior to calling this function (see
// OpenFirstAvailableMaster()).
// Get the name of the secondary pseudo terminal. A primary pseudo terminal
// should already be valid prior to calling this function (see
// OpenFirstAvailablePrimary()).
//
// RETURNS:
// NULL if no valid master pseudo terminal or if ptsname() fails.
// The name of the slave pseudo terminal as a NULL terminated C string
// NULL if no valid primary pseudo terminal or if ptsname() fails.
// The name of the secondary pseudo terminal as a NULL terminated C string
// that comes from static memory, so a copy of the string should be
// made as subsequent calls can change this value.
const char *PseudoTerminal::GetSlaveName(char *error_str,
size_t error_len) const {
const char *PseudoTerminal::GetSecondaryName(char *error_str,
size_t error_len) const {
if (error_str)
error_str[0] = '\0';
if (m_master_fd < 0) {
if (m_primary_fd < 0) {
if (error_str)
::snprintf(error_str, error_len, "%s",
"master file descriptor is invalid");
"primary file descriptor is invalid");
return nullptr;
}
const char *slave_name = ::ptsname(m_master_fd);
const char *secondary_name = ::ptsname(m_primary_fd);
if (error_str && slave_name == nullptr)
if (error_str && secondary_name == nullptr)
ErrnoToStr(error_str, error_len);
return slave_name;
return secondary_name;
}
// Fork a child process and have its stdio routed to a pseudo terminal.
//
// In the parent process when a valid pid is returned, the master file
// In the parent process when a valid pid is returned, the primary file
// descriptor can be used as a 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.
// secondary pseudo terminal and the primary 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, so be sure to call ReleaseMasterFileDescriptor() or
// ReleaseSlaveFileDescriptor() if any file descriptors are going to be used
// This class will close the file descriptors for the primary/secondary when the
// destructor is called, so be sure to call ReleasePrimaryFileDescriptor() or
// ReleaseSecondaryFileDescriptor() if any file descriptors are going to be used
// past the lifespan of this object.
//
// RETURNS:
@ -196,8 +198,8 @@ lldb::pid_t PseudoTerminal::Fork(char *error_str, size_t error_len) {
#if LLDB_ENABLE_POSIX
int flags = O_RDWR;
flags |= O_CLOEXEC;
if (OpenFirstAvailableMaster(flags, error_str, error_len)) {
// Successfully opened our master pseudo terminal
if (OpenFirstAvailablePrimary(flags, error_str, error_len)) {
// Successfully opened our primary pseudo terminal
pid = ::fork();
if (pid < 0) {
@ -208,32 +210,32 @@ lldb::pid_t PseudoTerminal::Fork(char *error_str, size_t error_len) {
// Child Process
::setsid();
if (OpenSlave(O_RDWR, error_str, error_len)) {
// Successfully opened slave
if (OpenSecondary(O_RDWR, error_str, error_len)) {
// Successfully opened secondary
// Master FD should have O_CLOEXEC set, but let's close it just in
// Primary FD should have O_CLOEXEC set, but let's close it just in
// case...
CloseMasterFileDescriptor();
ClosePrimaryFileDescriptor();
#if defined(TIOCSCTTY)
// Acquire the controlling terminal
if (::ioctl(m_slave_fd, TIOCSCTTY, (char *)0) < 0) {
if (::ioctl(m_secondary_fd, TIOCSCTTY, (char *)0) < 0) {
if (error_str)
ErrnoToStr(error_str, error_len);
}
#endif
// Duplicate all stdio file descriptors to the slave pseudo terminal
if (::dup2(m_slave_fd, STDIN_FILENO) != STDIN_FILENO) {
// Duplicate all stdio file descriptors to the secondary pseudo terminal
if (::dup2(m_secondary_fd, STDIN_FILENO) != STDIN_FILENO) {
if (error_str && !error_str[0])
ErrnoToStr(error_str, error_len);
}
if (::dup2(m_slave_fd, STDOUT_FILENO) != STDOUT_FILENO) {
if (::dup2(m_secondary_fd, STDOUT_FILENO) != STDOUT_FILENO) {
if (error_str && !error_str[0])
ErrnoToStr(error_str, error_len);
}
if (::dup2(m_slave_fd, STDERR_FILENO) != STDERR_FILENO) {
if (::dup2(m_secondary_fd, STDERR_FILENO) != STDERR_FILENO) {
if (error_str && !error_str[0])
ErrnoToStr(error_str, error_len);
}
@ -247,41 +249,43 @@ lldb::pid_t PseudoTerminal::Fork(char *error_str, size_t error_len) {
return pid;
}
// The master file descriptor accessor. This object retains ownership of the
// master file descriptor when this accessor is used. Use
// ReleaseMasterFileDescriptor() if you wish this object to release ownership
// of the master file descriptor.
// The primary file descriptor accessor. This object retains ownership of the
// primary file descriptor when this accessor is used. Use
// ReleasePrimaryFileDescriptor() if you wish this object to release ownership
// of the primary file descriptor.
//
// Returns the master file descriptor, or -1 if the master file descriptor is
// Returns the primary file descriptor, or -1 if the primary file descriptor is
// not currently valid.
int PseudoTerminal::GetMasterFileDescriptor() const { return m_master_fd; }
int PseudoTerminal::GetPrimaryFileDescriptor() const { return m_primary_fd; }
// The slave file descriptor accessor.
// The secondary file descriptor accessor.
//
// Returns the slave file descriptor, or -1 if the slave file descriptor is not
// currently valid.
int PseudoTerminal::GetSlaveFileDescriptor() const { return m_slave_fd; }
// Returns the secondary file descriptor, or -1 if the secondary file descriptor
// is not currently valid.
int PseudoTerminal::GetSecondaryFileDescriptor() const {
return m_secondary_fd;
}
// Release 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
// Release ownership of the primary pseudo terminal file descriptor without
// closing it. The destructor for this class will close the primary file
// descriptor if the ownership isn't released using this call and the primary
// file descriptor has been opened.
int PseudoTerminal::ReleaseMasterFileDescriptor() {
// Release ownership of the master pseudo terminal file descriptor without
int PseudoTerminal::ReleasePrimaryFileDescriptor() {
// Release ownership of the primary pseudo terminal file descriptor without
// closing it. (the destructor for this class will close it otherwise!)
int fd = m_master_fd;
m_master_fd = invalid_fd;
int fd = m_primary_fd;
m_primary_fd = invalid_fd;
return fd;
}
// 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
// Release ownership of the secondary pseudo terminal file descriptor without
// closing it. The destructor for this class will close the secondary file
// descriptor if the ownership isn't released using this call and the secondary
// file descriptor has been opened.
int PseudoTerminal::ReleaseSlaveFileDescriptor() {
// Release ownership of the slave pseudo terminal file descriptor without
int PseudoTerminal::ReleaseSecondaryFileDescriptor() {
// Release ownership of the secondary pseudo terminal file descriptor without
// closing it (the destructor for this class will close it otherwise!)
int fd = m_slave_fd;
m_slave_fd = invalid_fd;
int fd = m_secondary_fd;
m_secondary_fd = invalid_fd;
return fd;
}

View File

@ -362,7 +362,7 @@ PlatformLinux::DebugProcess(ProcessLaunchInfo &launch_info, Debugger &debugger,
// Hook up process PTY if we have one (which we should for local debugging
// with llgs).
int pty_fd = launch_info.GetPTY().ReleaseMasterFileDescriptor();
int pty_fd = launch_info.GetPTY().ReleasePrimaryFileDescriptor();
if (pty_fd != PseudoTerminal::invalid_fd) {
process_sp->SetSTDIOFileDescriptor(pty_fd);
LLDB_LOG(log, "hooked up STDIO pty to process");

View File

@ -194,10 +194,10 @@ lldb::ProcessSP PlatformAppleSimulator::DebugProcess(
process_sp->SetShouldDetach(false);
// If we didn't have any file actions, the pseudo terminal might have
// been used where the slave side was given as the file to open for
// stdin/out/err after we have already opened the master so we can
// been used where the secondary side was given as the file to open for
// stdin/out/err after we have already opened the primary so we can
// read/write stdin/out/err.
int pty_fd = launch_info.GetPTY().ReleaseMasterFileDescriptor();
int pty_fd = launch_info.GetPTY().ReleasePrimaryFileDescriptor();
if (pty_fd != PseudoTerminal::invalid_fd) {
process_sp->SetSTDIOFileDescriptor(pty_fd);
}

View File

@ -403,22 +403,25 @@ static Status HandleFileAction(ProcessLaunchInfo &launch_info,
case FileAction::eFileActionOpen: {
FileSpec file_spec = file_action->GetFileSpec();
if (file_spec) {
const int master_fd = launch_info.GetPTY().GetMasterFileDescriptor();
const int master_fd = launch_info.GetPTY().GetPrimaryFileDescriptor();
if (master_fd != PseudoTerminal::invalid_fd) {
// Check in case our file action open wants to open the slave
const char *slave_path = launch_info.GetPTY().GetSlaveName(NULL, 0);
if (slave_path) {
FileSpec slave_spec(slave_path);
if (file_spec == slave_spec) {
int slave_fd = launch_info.GetPTY().GetSlaveFileDescriptor();
if (slave_fd == PseudoTerminal::invalid_fd)
slave_fd = launch_info.GetPTY().OpenSlave(O_RDWR, nullptr, 0);
if (slave_fd == PseudoTerminal::invalid_fd) {
error.SetErrorStringWithFormat("unable to open slave pty '%s'",
slave_path);
// Check in case our file action open wants to open the secondary
const char *secondary_path =
launch_info.GetPTY().GetSecondaryName(NULL, 0);
if (secondary_path) {
FileSpec secondary_spec(secondary_path);
if (file_spec == secondary_spec) {
int secondary_fd =
launch_info.GetPTY().GetSecondaryFileDescriptor();
if (secondary_fd == PseudoTerminal::invalid_fd)
secondary_fd =
launch_info.GetPTY().OpenSecondary(O_RDWR, nullptr, 0);
if (secondary_fd == PseudoTerminal::invalid_fd) {
error.SetErrorStringWithFormat(
"unable to open secondary pty '%s'", secondary_path);
return error; // Failure
}
[options setValue:[NSNumber numberWithInteger:slave_fd]
[options setValue:[NSNumber numberWithInteger:secondary_fd]
forKey:key];
return error; // Success
}

View File

@ -331,7 +331,7 @@ PlatformNetBSD::DebugProcess(ProcessLaunchInfo &launch_info, Debugger &debugger,
// Hook up process PTY if we have one (which we should for local debugging
// with llgs).
int pty_fd = launch_info.GetPTY().ReleaseMasterFileDescriptor();
int pty_fd = launch_info.GetPTY().ReleasePrimaryFileDescriptor();
if (pty_fd != PseudoTerminal::invalid_fd) {
process_sp->SetSTDIOFileDescriptor(pty_fd);
LLDB_LOG(log, "hooked up STDIO pty to process");

View File

@ -380,7 +380,8 @@ Status ProcessFreeBSD::DoLaunch(Module *module,
FileSpec stdout_file_spec{};
FileSpec stderr_file_spec{};
const FileSpec dbg_pts_file_spec{launch_info.GetPTY().GetSlaveName(NULL, 0)};
const FileSpec dbg_pts_file_spec{
launch_info.GetPTY().GetSecondaryName(NULL, 0)};
file_action = launch_info.GetFileActionForFD(STDIN_FILENO);
stdin_file_spec =

View File

@ -855,7 +855,7 @@ bool ProcessMonitor::Launch(LaunchArgs *args) {
// terminal has already dupped the tty descriptors to stdin/out/err. This
// closes original fd from which they were copied (and avoids leaking
// descriptors to the debugged process.
terminal.CloseSlaveFileDescriptor();
terminal.CloseSecondaryFileDescriptor();
// Do not inherit setgid powers.
if (setgid(getgid()) != 0)
@ -939,7 +939,7 @@ bool ProcessMonitor::Launch(LaunchArgs *args) {
#endif
// Release the master terminal descriptor and pass it off to the
// ProcessMonitor instance. Similarly stash the inferior pid.
monitor->m_terminal_fd = terminal.ReleaseMasterFileDescriptor();
monitor->m_terminal_fd = terminal.ReleasePrimaryFileDescriptor();
monitor->m_pid = pid;
// Set the terminal fd to be in non blocking mode (it simplifies the

View File

@ -256,7 +256,7 @@ NativeProcessLinux::Factory::Launch(ProcessLaunchInfo &launch_info,
}
return std::unique_ptr<NativeProcessLinux>(new NativeProcessLinux(
pid, launch_info.GetPTY().ReleaseMasterFileDescriptor(), native_delegate,
pid, launch_info.GetPTY().ReleasePrimaryFileDescriptor(), native_delegate,
Info.GetArchitecture(), mainloop, {pid}));
}

View File

@ -95,7 +95,7 @@ NativeProcessNetBSD::Factory::Launch(ProcessLaunchInfo &launch_info,
Info.GetArchitecture().GetArchitectureName());
std::unique_ptr<NativeProcessNetBSD> process_up(new NativeProcessNetBSD(
pid, launch_info.GetPTY().ReleaseMasterFileDescriptor(), native_delegate,
pid, launch_info.GetPTY().ReleasePrimaryFileDescriptor(), native_delegate,
Info.GetArchitecture(), mainloop));
// Enable event reporting

View File

@ -70,11 +70,11 @@ Status DebuggerThread::DebugLaunch(const ProcessLaunchInfo &launch_info) {
Status result;
DebugLaunchContext *context = new DebugLaunchContext(this, launch_info);
llvm::Expected<HostThread> slave_thread = ThreadLauncher::LaunchThread(
"lldb.plugin.process-windows.slave[?]", DebuggerThreadLaunchRoutine,
context);
if (!slave_thread) {
result = Status(slave_thread.takeError());
llvm::Expected<HostThread> secondary_thread =
ThreadLauncher::LaunchThread("lldb.plugin.process-windows.secondary[?]",
DebuggerThreadLaunchRoutine, context);
if (!secondary_thread) {
result = Status(secondary_thread.takeError());
LLDB_LOG(log, "couldn't launch debugger thread. {0}", result);
}
@ -89,11 +89,11 @@ Status DebuggerThread::DebugAttach(lldb::pid_t pid,
Status result;
DebugAttachContext *context = new DebugAttachContext(this, pid, attach_info);
llvm::Expected<HostThread> slave_thread = ThreadLauncher::LaunchThread(
"lldb.plugin.process-windows.slave[?]", DebuggerThreadAttachRoutine,
context);
if (!slave_thread) {
result = Status(slave_thread.takeError());
llvm::Expected<HostThread> secondary_thread =
ThreadLauncher::LaunchThread("lldb.plugin.process-windows.secondary[?]",
DebuggerThreadAttachRoutine, context);
if (!secondary_thread) {
result = Status(secondary_thread.takeError());
LLDB_LOG(log, "couldn't attach to process '{0}'. {1}", pid, result);
}
@ -411,7 +411,7 @@ DebuggerThread::HandleCreateProcessEvent(const CREATE_PROCESS_DEBUG_INFO &info,
std::string thread_name;
llvm::raw_string_ostream name_stream(thread_name);
name_stream << "lldb.plugin.process-windows.slave[" << process_id << "]";
name_stream << "lldb.plugin.process-windows.secondary[" << process_id << "]";
name_stream.flush();
llvm::set_thread_name(thread_name);

View File

@ -48,7 +48,7 @@ NativeProcessWindows::NativeProcessWindows(ProcessLaunchInfo &launch_info,
NativeDelegate &delegate,
llvm::Error &E)
: NativeProcessProtocol(LLDB_INVALID_PROCESS_ID,
launch_info.GetPTY().ReleaseMasterFileDescriptor(),
launch_info.GetPTY().ReleasePrimaryFileDescriptor(),
delegate),
ProcessDebugger(), m_arch(launch_info.GetArchitecture()) {
ErrorAsOutParameter EOut(&E);

View File

@ -830,22 +830,23 @@ Status ProcessGDBRemote::DoLaunch(lldb_private::Module *exe_module,
// since 'O' packets can really slow down debugging if the inferior
// does a lot of output.
if ((!stdin_file_spec || !stdout_file_spec || !stderr_file_spec) &&
pty.OpenFirstAvailableMaster(O_RDWR | O_NOCTTY, nullptr, 0)) {
FileSpec slave_name{pty.GetSlaveName(nullptr, 0)};
pty.OpenFirstAvailablePrimary(O_RDWR | O_NOCTTY, nullptr, 0)) {
FileSpec secondary_name{pty.GetSecondaryName(nullptr, 0)};
if (!stdin_file_spec)
stdin_file_spec = slave_name;
stdin_file_spec = secondary_name;
if (!stdout_file_spec)
stdout_file_spec = slave_name;
stdout_file_spec = secondary_name;
if (!stderr_file_spec)
stderr_file_spec = slave_name;
stderr_file_spec = secondary_name;
}
LLDB_LOGF(
log,
"ProcessGDBRemote::%s adjusted STDIO paths for local platform "
"(IsHost() is true) using slave: stdin=%s, stdout=%s, stderr=%s",
"(IsHost() is true) using secondary: stdin=%s, stdout=%s, "
"stderr=%s",
__FUNCTION__,
stdin_file_spec ? stdin_file_spec.GetCString() : "<null>",
stdout_file_spec ? stdout_file_spec.GetCString() : "<null>",
@ -930,8 +931,8 @@ Status ProcessGDBRemote::DoLaunch(lldb_private::Module *exe_module,
SetPrivateState(SetThreadStopInfo(response));
if (!disable_stdio) {
if (pty.GetMasterFileDescriptor() != PseudoTerminal::invalid_fd)
SetSTDIOFileDescriptor(pty.ReleaseMasterFileDescriptor());
if (pty.GetPrimaryFileDescriptor() != PseudoTerminal::invalid_fd)
SetSTDIOFileDescriptor(pty.ReleasePrimaryFileDescriptor());
}
}
} else {

View File

@ -489,7 +489,7 @@ ScriptInterpreterPythonImpl::ScriptInterpreterPythonImpl(Debugger &debugger)
m_run_one_line_str_global(),
m_dictionary_name(m_debugger.GetInstanceName().AsCString()),
m_active_io_handler(eIOHandlerNone), m_session_is_active(false),
m_pty_slave_is_open(false), m_valid_session(true), m_lock_count(0),
m_pty_secondary_is_open(false), m_valid_session(true), m_lock_count(0),
m_command_thread_state(nullptr) {
InitializePrivate();

View File

@ -395,7 +395,7 @@ public:
std::string m_dictionary_name;
ActiveIOHandler m_active_io_handler;
bool m_session_is_active;
bool m_pty_slave_is_open;
bool m_pty_secondary_is_open;
bool m_valid_session;
uint32_t m_lock_count;
PyThreadState *m_command_thread_state;

View File

@ -1154,10 +1154,10 @@ Platform::DebugProcess(ProcessLaunchInfo &launch_info, Debugger &debugger,
process_sp->SetShouldDetach(false);
// If we didn't have any file actions, the pseudo terminal might have
// been used where the slave side was given as the file to open for
// been used where the secondary side was given as the file to open for
// stdin/out/err after we have already opened the master so we can
// read/write stdin/out/err.
int pty_fd = launch_info.GetPTY().ReleaseMasterFileDescriptor();
int pty_fd = launch_info.GetPTY().ReleasePrimaryFileDescriptor();
if (pty_fd != PseudoTerminal::invalid_fd) {
process_sp->SetSTDIOFileDescriptor(pty_fd);
}

View File

@ -88,21 +88,21 @@ private:
PseudoTerminal _pty;
int _pty_master_fd;
int _pty_slave_fd;
int _pty_secondary_fd;
std::unique_ptr<FilePointer> _el_slave_file;
std::unique_ptr<FilePointer> _el_secondary_file;
};
EditlineAdapter::EditlineAdapter()
: _editline_sp(), _pty(), _pty_master_fd(-1), _pty_slave_fd(-1),
_el_slave_file() {
: _editline_sp(), _pty(), _pty_master_fd(-1), _pty_secondary_fd(-1),
_el_secondary_file() {
lldb_private::Status error;
// Open the first master pty available.
char error_string[256];
error_string[0] = '\0';
if (!_pty.OpenFirstAvailableMaster(O_RDWR, error_string,
sizeof(error_string))) {
if (!_pty.OpenFirstAvailablePrimary(O_RDWR, error_string,
sizeof(error_string))) {
fprintf(stderr, "failed to open first available master pty: '%s'\n",
error_string);
return;
@ -111,24 +111,24 @@ EditlineAdapter::EditlineAdapter()
// Grab the master fd. This is a file descriptor we will:
// (1) write to when we want to send input to editline.
// (2) read from when we want to see what editline sends back.
_pty_master_fd = _pty.GetMasterFileDescriptor();
_pty_master_fd = _pty.GetPrimaryFileDescriptor();
// Open the corresponding slave pty.
if (!_pty.OpenSlave(O_RDWR, error_string, sizeof(error_string))) {
fprintf(stderr, "failed to open slave pty: '%s'\n", error_string);
// Open the corresponding secondary pty.
if (!_pty.OpenSecondary(O_RDWR, error_string, sizeof(error_string))) {
fprintf(stderr, "failed to open secondary pty: '%s'\n", error_string);
return;
}
_pty_slave_fd = _pty.GetSlaveFileDescriptor();
_pty_secondary_fd = _pty.GetSecondaryFileDescriptor();
_el_slave_file.reset(new FilePointer(fdopen(_pty_slave_fd, "rw")));
EXPECT_FALSE(nullptr == *_el_slave_file);
if (*_el_slave_file == nullptr)
_el_secondary_file.reset(new FilePointer(fdopen(_pty_secondary_fd, "rw")));
EXPECT_FALSE(nullptr == *_el_secondary_file);
if (*_el_secondary_file == nullptr)
return;
// Create an Editline instance.
_editline_sp.reset(new lldb_private::Editline("gtest editor", *_el_slave_file,
*_el_slave_file,
*_el_slave_file, false));
_editline_sp.reset(new lldb_private::Editline(
"gtest editor", *_el_secondary_file, *_el_secondary_file,
*_el_secondary_file, false));
_editline_sp->SetPrompt("> ");
// Hookup our input complete callback.
@ -136,8 +136,8 @@ EditlineAdapter::EditlineAdapter()
}
void EditlineAdapter::CloseInput() {
if (_el_slave_file != nullptr)
_el_slave_file.reset(nullptr);
if (_el_secondary_file != nullptr)
_el_secondary_file.reset(nullptr);
}
bool EditlineAdapter::SendLine(const std::string &line) {

View File

@ -102,17 +102,17 @@ TEST_F(MainLoopTest, TerminatesImmediately) {
TEST_F(MainLoopTest, DetectsEOF) {
PseudoTerminal term;
ASSERT_TRUE(term.OpenFirstAvailableMaster(O_RDWR, nullptr, 0));
ASSERT_TRUE(term.OpenSlave(O_RDWR | O_NOCTTY, nullptr, 0));
ASSERT_TRUE(term.OpenFirstAvailablePrimary(O_RDWR, nullptr, 0));
ASSERT_TRUE(term.OpenSecondary(O_RDWR | O_NOCTTY, nullptr, 0));
auto conn = std::make_unique<ConnectionFileDescriptor>(
term.ReleaseMasterFileDescriptor(), true);
term.ReleasePrimaryFileDescriptor(), true);
Status error;
MainLoop loop;
auto handle =
loop.RegisterReadObject(conn->GetReadObject(), make_callback(), error);
ASSERT_TRUE(error.Success());
term.CloseSlaveFileDescriptor();
term.CloseSecondaryFileDescriptor();
ASSERT_TRUE(loop.Run().Success());
ASSERT_EQ(1u, callback_count);