Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lldb/include/lldb/Host/ProcessLaunchInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ class ProcessLaunchInfo : public ProcessInfo {

bool MonitorProcess() const;

PseudoTerminal &GetPTY() { return *m_pty; }
std::shared_ptr<PseudoTerminal> GetPTY() const { return m_pty; }

void SetLaunchEventData(const char *data) { m_event_data.assign(data); }

Expand Down
40 changes: 31 additions & 9 deletions lldb/include/lldb/Host/PseudoTerminal.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,14 @@ class PseudoTerminal {

/// Destructor
///
/// 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();
/// The destructor will close the primary and secondary file
/// descriptor/HANDLEs if they are valid and ownership has not been released
/// using PseudoTerminal::Close().
virtual ~PseudoTerminal();

/// Close all the file descriptors or Handles of the PseudoTerminal if they
/// are valid.
virtual void Close();

/// Close the primary file descriptor if it is valid.
void ClosePrimaryFileDescriptor();
Expand All @@ -59,8 +62,7 @@ class PseudoTerminal {
///
/// 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()
/// @li PseudoTerminal::ReleasePrimaryFileDescriptor()
///
/// \return
/// \b Parent process: a child process ID that is greater
Expand All @@ -82,6 +84,16 @@ class PseudoTerminal {
/// \see PseudoTerminal::ReleasePrimaryFileDescriptor()
int GetPrimaryFileDescriptor() const;

/// The primary HANDLE accessor.
///
/// This object retains ownership of the primary HANDLE when this
/// accessor is used.
///
/// \return
/// The primary HANDLE, or INVALID_HANDLE_VALUE if the primary HANDLE is
/// not currently valid.
virtual void *GetPrimaryHandle() const { return ((void *)(long long)-1); };

/// The secondary file descriptor accessor.
///
/// This object retains ownership of the secondary file descriptor when this
Expand All @@ -105,7 +117,17 @@ class PseudoTerminal {
/// The name of the secondary pseudo terminal.
///
/// \see PseudoTerminal::OpenFirstAvailablePrimary()
std::string GetSecondaryName() const;
virtual std::string GetSecondaryName() const;

/// The underlying Windows Pseudo Terminal HANDLE's accessor.
///
/// This object retains ownership of the ConPTY's HANDLE when this
/// accessor is used.
///
/// \return
/// The primary HANDLE, or INVALID_HANDLE_VALUE if the primary HANDLE is
/// not currently valid.
virtual void *GetPseudoTerminalHandle() { return ((void *)(long long)-1); };

/// Open the first available pseudo terminal.
///
Expand All @@ -126,7 +148,7 @@ class PseudoTerminal {
///
/// \see PseudoTerminal::GetPrimaryFileDescriptor() @see
/// PseudoTerminal::ReleasePrimaryFileDescriptor()
llvm::Error OpenFirstAvailablePrimary(int oflag);
virtual llvm::Error OpenFirstAvailablePrimary(int oflag);

/// Open the secondary for the current primary pseudo terminal.
///
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
//===-- ConnectionPseudoTerminalWindows.h ------------------------*- C++
//-*-===//
Comment on lines +1 to +2
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
//===-- ConnectionPseudoTerminalWindows.h ------------------------*- C++
//-*-===//
//===----------------------------------------------------------------------===//

See https://discourse.llvm.org/t/is-c-in-header-files-still-relevant/83124

//
// 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 liblldb_Host_windows_ConnectionPseudoConsoleWindows_h_
#define liblldb_Host_windows_ConnectionPseudoConsoleWindows_h_

#include "lldb/Host/windows/PseudoTerminalWindows.h"
#include "lldb/Host/windows/windows.h"
#include "lldb/Utility/Connection.h"
#include "lldb/Utility/Status.h"
#include "lldb/lldb-types.h"

namespace lldb_private {

class ConnectionPseudoTerminal : public lldb_private::Connection {
public:
ConnectionPseudoTerminal();

ConnectionPseudoTerminal(std::shared_ptr<PseudoTerminal> pty, bool owns_file);

~ConnectionPseudoTerminal() override;

bool IsConnected() const override;

lldb::ConnectionStatus Connect(llvm::StringRef url,
Status *error_ptr) override;

lldb::ConnectionStatus Disconnect(Status *error_ptr) override;

size_t Read(void *dst, size_t dst_len, const Timeout<std::micro> &timeout,
lldb::ConnectionStatus &status, Status *error_ptr) override;

size_t Write(const void *src, size_t src_len, lldb::ConnectionStatus &status,
Status *error_ptr) override;

std::string GetURI() override { return ""; };

bool InterruptRead() override;

protected:
std::shared_ptr<PseudoTerminal> m_pty;
OVERLAPPED m_overlapped;
bool m_owns_file;
HANDLE m_event_handles[2];

enum { kBytesAvailableEvent, kInterruptEvent };

private:
ConnectionPseudoTerminal(const ConnectionPseudoTerminal &) = delete;
const ConnectionPseudoTerminal &
operator=(const ConnectionPseudoTerminal &) = delete;
};
} // namespace lldb_private

#endif
29 changes: 29 additions & 0 deletions lldb/include/lldb/Host/windows/ProcessLauncherWindows.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@

#include "lldb/Host/ProcessLauncher.h"
#include "lldb/Host/windows/windows.h"
#include "lldb/Utility/Args.h"
#include "lldb/Utility/Environment.h"
#include "llvm/Support/ErrorOr.h"

namespace lldb_private {

Expand All @@ -23,6 +26,32 @@ class ProcessLauncherWindows : public ProcessLauncher {

protected:
HANDLE GetStdioHandle(const ProcessLaunchInfo &launch_info, int fd);

/// Create a UTF-16 environment block to use with CreateProcessW.
///
/// The buffer is a sequence of null-terminated UTF-16 strings, followed by an
/// extra L'\0' (two bytes of 0). An empty environment must have one
/// empty string, followed by an extra L'\0'.
///
/// The keys are sorted to comply with the CreateProcess' calling convention.
///
/// Ensure that the resulting buffer is used in conjunction with
/// CreateProcessW and be sure that dwCreationFlags includes
/// CREATE_UNICODE_ENVIRONMENT.
///
/// \param env The Environment object to convert.
/// \returns The sorted sequence of environment variables and their values,
/// separated by null terminators.
static std::vector<wchar_t> CreateEnvironmentBufferW(const Environment &env);

/// Flattens an Args object into a Windows command-line wide string.
///
/// Returns an empty string if args is empty.
///
/// \param args The Args object to flatten.
/// \returns A wide string containing the flattened command line.
static llvm::ErrorOr<std::wstring>
GetFlattenedWindowsCommandStringW(Args args);
};
}

Expand Down
37 changes: 37 additions & 0 deletions lldb/include/lldb/Host/windows/PseudoTerminalWindows.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
//===-- PseudoTerminalWindows.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 liblldb_Host_Windows_PseudoTerminalWindows_H_
#define liblldb_Host_Windows_PseudoTerminalWindows_H_

#include "lldb/Host/PseudoTerminal.h"
#include "lldb/Host/windows/windows.h"

namespace lldb_private {

class PseudoTerminalWindows : public PseudoTerminal {

public:
void Close() override;

HPCON GetPseudoTerminalHandle() override { return m_conpty_handle; };

HANDLE GetPrimaryHandle() const override { return m_conpty_output; };

std::string GetSecondaryName() const override { return ""; };

llvm::Error OpenFirstAvailablePrimary(int oflag) override;

protected:
HANDLE m_conpty_handle = INVALID_HANDLE_VALUE;
HANDLE m_conpty_output = INVALID_HANDLE_VALUE;
HANDLE m_conpty_input = INVALID_HANDLE_VALUE;
};
}; // namespace lldb_private

#endif // liblldb_Host_Windows_PseudoTerminalWindows_H_
5 changes: 3 additions & 2 deletions lldb/include/lldb/Host/windows/windows.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@
#ifndef LLDB_lldb_windows_h_
#define LLDB_lldb_windows_h_

#define NTDDI_VERSION NTDDI_VISTA
// #define NTDDI_VERSION NTDDI_VISTA
#undef _WIN32_WINNT // undef a previous definition to avoid warning
#define _WIN32_WINNT _WIN32_WINNT_VISTA
// #define _WIN32_WINNT _WIN32_WINNT_VISTA
#define WIN32_LEAN_AND_MEAN
#define NOGDI
#undef NOMINMAX // undef a previous definition to avoid warning
Expand All @@ -26,6 +26,7 @@
#undef near
#undef FAR
#undef NEAR
#undef WIN32_MEMORY_INFORMATION_CLASS
#define FAR
#define NEAR

Expand Down
30 changes: 30 additions & 0 deletions lldb/include/lldb/Target/Process.h
Original file line number Diff line number Diff line change
Expand Up @@ -2534,8 +2534,38 @@ void PruneThreadPlans();

void CalculateExecutionContext(ExecutionContext &exe_ctx) override;

/// Associates a file descriptor with the process's STDIO handling
/// and configures an asynchronous reading of that descriptor.
///
/// This method installs a ConnectionFileDescriptor for the passed file
/// descriptor and starts a dedicated read thread. If the read thread starts
/// successfully, the method also ensures that an IOHandlerProcessSTDIO is
/// created to manage user input to the process.
///
/// The descriptor's ownership is transferred to the underlying
/// ConnectionFileDescriptor.
///
/// \param[in] fd
/// The file descriptor to use for process STDIO communication. It's
/// assumed to be valid and will be managed by the newly created
/// connection.
///
/// \see lldb_private::Process::STDIOReadThreadBytesReceived()
/// \see lldb_private::IOHandlerProcessSTDIO
/// \see lldb_private::ConnectionFileDescriptor
void SetSTDIOFileDescriptor(int file_descriptor);

/// Windows equivalent of Process::SetSTDIOFileDescriptor, with a
/// PseudoTerminalWindows instead of a file descriptor.
///
/// \param pty
/// The PseudoTerminal to use for process STDIO communication. It is not
/// managed by the created read thread.
///
/// \see lldb_private::ConnectionPseudoTerminalWindows
virtual void
SetPseudoTerminalHandle(const std::shared_ptr<PseudoTerminal> &pty) {};

// Add a permanent region of memory that should never be read or written to.
// This can be used to ensure that memory reads or writes to certain areas of
// memory never end up being sent to the DoReadMemory or DoWriteMemory
Expand Down
2 changes: 2 additions & 0 deletions lldb/source/Host/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ add_host_subdirectory(posix
if (CMAKE_SYSTEM_NAME MATCHES "Windows")
add_host_subdirectory(windows
windows/ConnectionGenericFileWindows.cpp
windows/ConnectionPseudoTerminalWindows.cpp
windows/FileSystem.cpp
windows/Host.cpp
windows/HostInfoWindows.cpp
Expand All @@ -75,6 +76,7 @@ if (CMAKE_SYSTEM_NAME MATCHES "Windows")
windows/MainLoopWindows.cpp
windows/PipeWindows.cpp
windows/ProcessLauncherWindows.cpp
windows/PseudoTerminalWindows.cpp
windows/ProcessRunLock.cpp
)
else()
Expand Down
19 changes: 16 additions & 3 deletions lldb/source/Host/common/ProcessLaunchInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@
#include "llvm/Support/ConvertUTF.h"
#include "llvm/Support/FileSystem.h"

#if !defined(_WIN32)
#ifdef _WIN32
#include "lldb/Host/windows/PseudoTerminalWindows.h"
#else
#include <climits>
#endif

Expand All @@ -31,7 +33,12 @@ using namespace lldb_private;

ProcessLaunchInfo::ProcessLaunchInfo()
: ProcessInfo(), m_working_dir(), m_plugin_name(), m_flags(0),
m_file_actions(), m_pty(new PseudoTerminal), m_monitor_callback(nullptr) {
m_file_actions(), m_monitor_callback(nullptr) {
#ifdef _WIN32
m_pty = std::make_shared<PseudoTerminalWindows>();
#else
m_pty = std::make_shared<PseudoTerminal>();
#endif
}

ProcessLaunchInfo::ProcessLaunchInfo(const FileSpec &stdin_file_spec,
Expand All @@ -40,7 +47,13 @@ ProcessLaunchInfo::ProcessLaunchInfo(const FileSpec &stdin_file_spec,
const FileSpec &working_directory,
uint32_t launch_flags)
: ProcessInfo(), m_working_dir(), m_plugin_name(), m_flags(launch_flags),
m_file_actions(), m_pty(new PseudoTerminal) {
m_file_actions() {
#ifdef _WIN32
m_pty = std::make_shared<PseudoTerminalWindows>();
#else
m_pty = std::make_shared<PseudoTerminal>();
#endif

if (stdin_file_spec) {
FileAction file_action;
const bool read = true;
Expand Down
12 changes: 4 additions & 8 deletions lldb/source/Host/common/PseudoTerminal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "lldb/Host/PseudoTerminal.h"
#include "lldb/Host/Config.h"
#include "lldb/Host/FileSystem.h"
#include "lldb/Host/windows/windows.h"
#include "llvm/Support/Errc.h"
#include "llvm/Support/Errno.h"
#include <cassert>
Expand All @@ -29,16 +30,11 @@

using namespace lldb_private;

// PseudoTerminal constructor
PseudoTerminal::PseudoTerminal() = default;

// Destructor
//
// 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() {
PseudoTerminal::~PseudoTerminal() { Close(); }

void PseudoTerminal::Close() {
ClosePrimaryFileDescriptor();
CloseSecondaryFileDescriptor();
}
Expand Down
Loading
Loading