================
@@ -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