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

Reply via email to