================
@@ -956,4 +947,142 @@ Status ProcessWindows::DisableWatchpoint(WatchpointSP
wp_sp, bool notify) {
return error;
}
+
+class IOHandlerProcessSTDIOWindows : public IOHandler {
+public:
+ IOHandlerProcessSTDIOWindows(Process *process, HANDLE conpty_input)
+ : IOHandler(process->GetTarget().GetDebugger(),
+ IOHandler::Type::ProcessIO),
+ m_process(process),
+ m_read_file(GetInputFD(), File::eOpenOptionReadOnly, false),
+ m_write_file(conpty_input) {
+ m_pipe.CreateNew();
+ }
+
+ ~IOHandlerProcessSTDIOWindows() override = default;
+
+ void SetIsRunning(bool running) {
+ std::lock_guard<std::mutex> guard(m_mutex);
+ SetIsDone(!running);
+ m_is_running = running;
+ }
+
+ void Run() override {
+ if (!m_read_file.IsValid() || m_write_file == INVALID_HANDLE_VALUE ||
+ !m_pipe.CanRead() || !m_pipe.CanWrite()) {
+ 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};
+
+ while (true) {
+ {
+ std::lock_guard<std::mutex> guard(m_mutex);
+ if (GetIsDone())
+ goto exit_loop;
+ }
+
+ DWORD result = WaitForMultipleObjects(2, waitHandles, FALSE, INFINITE);
+ switch (result) {
+ case WAIT_FAILED:
+ goto exit_loop;
+ case WAIT_OBJECT_0: {
+ char ch = 0;
+ DWORD read = 0;
+ if (!ReadFile(hStdin, &ch, 1, &read, nullptr) || read != 1)
+ goto exit_loop;
+
+ DWORD written = 0;
+ if (!WriteFile(m_write_file, &ch, 1, &written, nullptr) || written !=
1)
+ goto exit_loop;
+ break;
+ }
+ case WAIT_OBJECT_0 + 1: {
+ char ch = 0;
+ DWORD read = 0;
+ if (!ReadFile(hInterrupt, &ch, 1, &read, nullptr) || read != 1)
+ goto exit_loop;
+
+ if (ch == eControlOpQuit)
+ goto exit_loop;
+ if (ch == eControlOpInterrupt &&
+ StateIsRunningState(m_process->GetState()))
+ m_process->SendAsyncInterrupt();
+ break;
+ }
+ default:
+ goto exit_loop;
+ }
+ }
+
+ exit_loop:;
+ SetIsRunning(false);
+ }
+
+ void Cancel() override {
+ std::lock_guard<std::mutex> guard(m_mutex);
+ SetIsDone(true);
+ if (m_is_running) {
+ char ch = eControlOpQuit;
+ if (llvm::Error err = m_pipe.Write(&ch, 1).takeError()) {
+ LLDB_LOG_ERROR(GetLog(LLDBLog::Process), std::move(err),
+ "Pipe write failed: {0}");
+ }
+ }
+ }
+
+ bool Interrupt() override {
+ if (m_active) {
+ char ch = eControlOpInterrupt;
+ return !errorToBool(m_pipe.Write(&ch, 1).takeError());
+ }
+ if (StateIsRunningState(m_process->GetState())) {
+ m_process->SendAsyncInterrupt();
+ return true;
+ }
+ return false;
+ }
+
+ void GotEOF() override {}
----------------
ashgti wrote:
Should we also interrupt on EOF? I think we do that in IOHandlerEditline, but
it may not be correct here.
https://github.com/llvm/llvm-project/pull/168729
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits