llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-lldb Author: Charles Zablit (charles-zablit) <details> <summary>Changes</summary> --- Patch is 59.24 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/168729.diff 33 Files Affected: - (modified) lldb/include/lldb/Host/ProcessLaunchInfo.h (+1-1) - (modified) lldb/include/lldb/Host/PseudoTerminal.h (+31-9) - (added) lldb/include/lldb/Host/windows/ConnectionPseudoTerminalWindows.h (+61) - (modified) lldb/include/lldb/Host/windows/ProcessLauncherWindows.h (+29) - (added) lldb/include/lldb/Host/windows/PseudoTerminalWindows.h (+37) - (modified) lldb/include/lldb/Host/windows/windows.h (+3-2) - (modified) lldb/include/lldb/Target/Process.h (+30) - (modified) lldb/source/Host/CMakeLists.txt (+2) - (modified) lldb/source/Host/common/ProcessLaunchInfo.cpp (+16-3) - (modified) lldb/source/Host/common/PseudoTerminal.cpp (+4-8) - (added) lldb/source/Host/windows/ConnectionPseudoTerminalWindows.cpp (+191) - (modified) lldb/source/Host/windows/ProcessLauncherWindows.cpp (+91-73) - (added) lldb/source/Host/windows/PseudoTerminalWindows.cpp (+68) - (modified) lldb/source/Interpreter/ScriptInterpreter.cpp (+1-1) - (modified) lldb/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.cpp (+1-1) - (modified) lldb/source/Plugins/Platform/MacOSX/objcxx/PlatformiOSSimulatorCoreSimulatorSupport.mm (+5-5) - (modified) lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp (+1-1) - (modified) lldb/source/Plugins/Platform/QemuUser/PlatformQemuUser.cpp (+2-2) - (modified) lldb/source/Plugins/Platform/Windows/PlatformWindows.cpp (+10-2) - (modified) lldb/source/Plugins/Process/AIX/NativeProcessAIX.cpp (+3-2) - (modified) lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.cpp (+2-2) - (modified) lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp (+2-2) - (modified) lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp (+2-2) - (modified) lldb/source/Plugins/Process/Windows/Common/NativeProcessWindows.cpp (+3-3) - (modified) lldb/source/Plugins/Process/Windows/Common/ProcessWindows.cpp (+17-16) - (modified) lldb/source/Plugins/Process/Windows/Common/ProcessWindows.h (+4-4) - (modified) lldb/source/Target/Platform.cpp (+1-1) - (modified) lldb/source/Target/Process.cpp (+9-8) - (modified) lldb/test/API/commands/platform/basic/TestPlatformCommand.py (+1) - (modified) lldb/test/API/tools/lldb-dap/launch/TestDAP_launch.py (-1) - (modified) lldb/tools/lldb-dap/tool/lldb-dap.cpp (+3) - (modified) lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp (+19-15) - (modified) llvm/utils/gn/secondary/lldb/source/Host/BUILD.gn (+2) ``````````diff diff --git a/lldb/include/lldb/Host/ProcessLaunchInfo.h b/lldb/include/lldb/Host/ProcessLaunchInfo.h index 25762bc65295d..50a5af604ee26 100644 --- a/lldb/include/lldb/Host/ProcessLaunchInfo.h +++ b/lldb/include/lldb/Host/ProcessLaunchInfo.h @@ -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); } diff --git a/lldb/include/lldb/Host/PseudoTerminal.h b/lldb/include/lldb/Host/PseudoTerminal.h index bd1e2f56241b2..b61c213e138cb 100644 --- a/lldb/include/lldb/Host/PseudoTerminal.h +++ b/lldb/include/lldb/Host/PseudoTerminal.h @@ -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(); @@ -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 @@ -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 @@ -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. /// @@ -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. /// diff --git a/lldb/include/lldb/Host/windows/ConnectionPseudoTerminalWindows.h b/lldb/include/lldb/Host/windows/ConnectionPseudoTerminalWindows.h new file mode 100644 index 0000000000000..6283312db7b8d --- /dev/null +++ b/lldb/include/lldb/Host/windows/ConnectionPseudoTerminalWindows.h @@ -0,0 +1,61 @@ +//===-- ConnectionPseudoTerminalWindows.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_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 diff --git a/lldb/include/lldb/Host/windows/ProcessLauncherWindows.h b/lldb/include/lldb/Host/windows/ProcessLauncherWindows.h index 81aea5b2022a5..a04077a5e1d03 100644 --- a/lldb/include/lldb/Host/windows/ProcessLauncherWindows.h +++ b/lldb/include/lldb/Host/windows/ProcessLauncherWindows.h @@ -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 { @@ -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); }; } diff --git a/lldb/include/lldb/Host/windows/PseudoTerminalWindows.h b/lldb/include/lldb/Host/windows/PseudoTerminalWindows.h new file mode 100644 index 0000000000000..8698ae2f8b804 --- /dev/null +++ b/lldb/include/lldb/Host/windows/PseudoTerminalWindows.h @@ -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_ \ No newline at end of file diff --git a/lldb/include/lldb/Host/windows/windows.h b/lldb/include/lldb/Host/windows/windows.h index d53d4b9967268..2047e602291fc 100644 --- a/lldb/include/lldb/Host/windows/windows.h +++ b/lldb/include/lldb/Host/windows/windows.h @@ -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 @@ -26,6 +26,7 @@ #undef near #undef FAR #undef NEAR +#undef WIN32_MEMORY_INFORMATION_CLASS #define FAR #define NEAR diff --git a/lldb/include/lldb/Target/Process.h b/lldb/include/lldb/Target/Process.h index c1f9785e76f90..17a8ce713302a 100644 --- a/lldb/include/lldb/Target/Process.h +++ b/lldb/include/lldb/Target/Process.h @@ -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 diff --git a/lldb/source/Host/CMakeLists.txt b/lldb/source/Host/CMakeLists.txt index c9e8afe48fcde..1657dadf5ffe7 100644 --- a/lldb/source/Host/CMakeLists.txt +++ b/lldb/source/Host/CMakeLists.txt @@ -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 @@ -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() diff --git a/lldb/source/Host/common/ProcessLaunchInfo.cpp b/lldb/source/Host/common/ProcessLaunchInfo.cpp index 49159cca9c57c..c3beef7031f18 100644 --- a/lldb/source/Host/common/ProcessLaunchInfo.cpp +++ b/lldb/source/Host/common/ProcessLaunchInfo.cpp @@ -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 @@ -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, @@ -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; diff --git a/lldb/source/Host/common/PseudoTerminal.cpp b/lldb/source/Host/common/PseudoTerminal.cpp index 53e91aff212a4..4d062c3618523 100644 --- a/lldb/source/Host/common/PseudoTerminal.cpp +++ b/lldb/source/Host/common/PseudoTerminal.cpp @@ -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> @@ -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(); } diff --git a/lldb/source/Host/windows/ConnectionPseudoTerminalWindows.cpp b/lldb/source/Host/windows/ConnectionPseudoTerminalWindows.cpp new file mode 100644 index 0000000000000..b00fd745bc409 --- /dev/null +++ b/lldb/source/Host/windows/ConnectionPseudoTerminalWindows.cpp @@ -0,0 +1,191 @@ +//===-- ConnectionPseudoConsoleWindowsWindows.cpp +//----------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "lldb/Host/windows/ConnectionPseudoTerminalWindows.h" +#include "lldb/Utility/LLDBLog.h" +#include "lldb/Utility/Log.h" +#include "lldb/Utility/Status.h" +#include "lldb/Utility/Timeout.h" + +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/ConvertUTF.h" + +using namespace lldb; +using namespace lldb_private; + +class ReturnInfo { +public: + void Set(size_t bytes, ConnectionStatus status, DWORD error_code) { + m_error = Status(error_code, eErrorTypeWin32); + m_bytes = bytes; + m_status = status; + } + + void Set(size_t bytes, ConnectionStatus status, llvm::StringRef error_msg) { + m_error = Status::FromErrorString(error_msg.data()); + m_bytes = bytes; + m_status = status; + } + + size_t GetBytes() const { return m_bytes; } + ConnectionStatus GetStatus() const { return m_status; } + const Status &GetError() const { return m_error; } + +private: + Status m_error; + size_t m_bytes; + ConnectionStatus m_status; +}; + +ConnectionPseudoTerminal::ConnectionPseudoTerminal() + : m_pty(nullptr), m_owns_file(false) { + ::ZeroMemory(&m_overlapped, sizeof(m_overlapped)); +} + +ConnectionPseudoTerminal::ConnectionPseudoTerminal( + std::shared_ptr<PseudoTerminal> pty, bool owns_file) + : m_pty(pty), m_owns_file(owns_file) { + ::ZeroMemory(&m_overlapped, sizeof(m_overlapped)); +} + +ConnectionPseudoTerminal::~ConnectionPseudoTerminal() {} + +lldb::ConnectionStatus ConnectionPseudoTerminal::Connect(llvm::StringRef url, + Status *error_ptr) { + if (IsConnected()) + return eConnectionStatusSuccess; + return eConnectionStatusNoConnection; +} + +bool ConnectionPseudoTerminal::IsConnected() const { + return m_pty && (m_pty->GetPrimaryHandle() != INVALID_HANDLE_VALUE); +} + +lldb::ConnectionStatus ConnectionPseudoTerminal::Disconnect(Status *error_ptr) { + Log *log = GetLog(LLDBLog::Connection); + LLDB_LOGF(log, "%p ConnectionPseudoTerminal::Disconnect ()", + static_cast<void *>(this)); + + if (!IsConnected()) + return eConnectionStatusSuccess; + + m_pty->Close(); + return eConnectionStatusSuccess; +} + +size_t ConnectionPseudoTerminal::Read(void *dst, size_t dst_len, + const Timeout<std::micro> &timeout, + lldb::ConnectionStatus &status, + Status *error_ptr) { + ReturnInfo return_info; + DWORD bytes_read = 0; + BOOL result = false; + + if (error_ptr) + error_ptr->Clear(); + + HANDLE hInput = m_pty->GetPrimaryHandle(); + + if (!IsConnected()) { + return_info.Set(0, eConnectionStatusNoConnection, ERROR_INVALID_HANDLE); + goto finish; + } + + // Setup OVERLAPPED event + m_overlapped.hEvent = m_event_handles[kBytesAvailableEvent]; + + result = + ::ReadFile(hInput, dst, static_cast<DWORD>(dst_len), NULL, &m_overlapped); + if (result || ::GetLastError() == ERROR_IO_PENDING) { + if (!result) { + // Operation pending: wait for completion or interrupt + DWORD milliseconds = + timeout ? static_cast<DWORD>( + std::chrono::duration_cast<std::chrono::milliseconds>( + *timeout) + .count()) + : INFINITE; + + DWORD wait_result = ::WaitForMultipleObjects( + static_cast<DWORD>(std::size(m_event_handles)), m_event_handles, + FALSE, milliseconds); + + switch (wait_result) { + case WAIT_OBJECT_0 + kBytesAvailableEvent: + break; // Data ready + case WAIT_OBJECT_0 + kInterruptEvent: + return_info.Set(0, eConnectionStatusInterrupted, 0); + goto finish; + case WAIT_TIMEOUT: + return_info.Set(0, eConnectionStatusTimedOut, 0); + goto finish; + case WAIT_FAILED: + return_info.Set(0, eConnectionStatusError, ::GetLastError()); + goto finish; + } + } + + // Get actual number of bytes read + if (!::GetOverlappedResult(hInput, &m_overlapped, &bytes_read, FALSE)) { + DWORD err = ::GetLastError(); + if (err == ERROR_HANDLE_EOF || err == ERROR_OPERATION_ABORTED || + err == ERROR_BROKEN_PIPE) + return_info.Set(bytes_read, eConnectionStatusEndOfFile, 0); + ... [truncated] `````````` </details> https://github.com/llvm/llvm-project/pull/168729 _______________________________________________ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
