================
@@ -958,31 +958,75 @@ class IOHandlerProcessSTDIOWindows : public IOHandler {
                   IOHandler::Type::ProcessIO),
         m_process(process),
         m_read_file(GetInputFD(), File::eOpenOptionReadOnly, false),
-        m_write_file(conpty_input) {
-    m_pipe.CreateNew();
+        m_write_file(conpty_input),
+        m_interrupt_event(
+            CreateEvent(/*lpEventAttributes=*/NULL, /*bManualReset=*/FALSE,
+                        /*bInitialState=*/FALSE, /*lpName=*/NULL)) {}
+
+  ~IOHandlerProcessSTDIOWindows() override {
+    if (m_interrupt_event != INVALID_HANDLE_VALUE)
+      ::CloseHandle(m_interrupt_event);
   }
 
-  ~IOHandlerProcessSTDIOWindows() override = default;
-
   void SetIsRunning(bool running) {
     std::lock_guard<std::mutex> guard(m_mutex);
     SetIsDone(!running);
     m_is_running = running;
   }
 
+  /// Peek the console for input. If it has any, drain the pipe until text 
input
+  /// is found or the pipe is empty.
+  ///
+  /// \param hStdin
+  ///     The handle to the standard input's pipe.
+  ///
+  /// \return
+  ///     true if the pipe has text input.
+  llvm::Expected<bool> ConsoleHasTextInput(const HANDLE hStdin) {
+    // Check if there are already characters buffered. Pressing enter counts as
+    // 2 characters '\r\n' and only one of them is a keyDown event.
+    DWORD bytesAvailable = 0;
+    if (PeekNamedPipe(hStdin, NULL, 0, NULL, &bytesAvailable, NULL)) {
+      if (bytesAvailable > 0)
+        return true;
+    }
+
+    while (true) {
+      INPUT_RECORD inputRecord;
+      DWORD numRead = 0;
+      if (!PeekConsoleInput(hStdin, &inputRecord, 1, &numRead))
+        return llvm::createStringError("Failed to peek standard input.");
+
+      if (numRead == 0)
+        return false;
+
+      if (inputRecord.EventType == KEY_EVENT &&
+          inputRecord.Event.KeyEvent.bKeyDown &&
+          inputRecord.Event.KeyEvent.uChar.AsciiChar != 0)
+        return true;
+
+      if (!ReadConsoleInput(hStdin, &inputRecord, 1, &numRead))
+        return llvm::createStringError("Failed to read standard input.");
+    }
+  }
+
   void Run() override {
-    if (!m_read_file.IsValid() || m_write_file == INVALID_HANDLE_VALUE ||
-        !m_pipe.CanRead() || !m_pipe.CanWrite()) {
+    if (!m_read_file.IsValid() || m_write_file == INVALID_HANDLE_VALUE) {
       SetIsDone(true);
       return;
     }
 
     SetIsDone(false);
     SetIsRunning(true);
 
-    HANDLE hStdin = (HANDLE)_get_osfhandle(m_read_file.GetDescriptor());
-    HANDLE hInterrupt = (HANDLE)_get_osfhandle(m_pipe.GetReadFileDescriptor());
-    HANDLE waitHandles[2] = {hStdin, hInterrupt};
+    HANDLE hStdin = m_read_file.GetWaitableHandle();
+    HANDLE waitHandles[2] = {hStdin, m_interrupt_event};
+
+    DWORD consoleMode;
+    bool isConsole = GetConsoleMode(hStdin, &consoleMode) != 0;
+    DWORD oldConsoleMode = consoleMode;
+    SetConsoleMode(hStdin,
+                   consoleMode & ~ENABLE_LINE_INPUT & ~ENABLE_ECHO_INPUT);
----------------
Nerixyz wrote:

Could you add a short comment here why we do this? If I understood correctly: 
to read the console character by character without printing the characters to 
the screen.

https://github.com/llvm/llvm-project/pull/175812
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to