From 11adefd8393a03857ff731228f94ebc3b6e96aa6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Tue, 11 Jul 2023 19:45:16 +0800 Subject: [PATCH] Processing (Windows): fix hanging when executing cygwin processes --- src/common/processing_linux.c | 2 +- src/common/processing_windows.c | 39 ++++++++++++++++++--------------- 2 files changed, 22 insertions(+), 19 deletions(-) diff --git a/src/common/processing_linux.c b/src/common/processing_linux.c index 6f7dadb5e..9a97b359f 100644 --- a/src/common/processing_linux.c +++ b/src/common/processing_linux.c @@ -49,7 +49,7 @@ const char* ffProcessAppendOutput(FFstrbuf* buffer, char* const argv[], bool use } else if (pollfd.revents & POLLHUP) { - return "Child process closed its end (nothing to read)"; + return NULL; } } diff --git a/src/common/processing_windows.c b/src/common/processing_windows.c index 10ca7adbf..ea304606b 100644 --- a/src/common/processing_windows.c +++ b/src/common/processing_windows.c @@ -82,31 +82,34 @@ const char* ffProcessAppendOutput(FFstrbuf* buffer, char* const argv[], bool use DWORD nRead = 0; OVERLAPPED overlapped = {}; // ReadFile always completes synchronously if the pipe is not created with FILE_FLAG_OVERLAPPED - if (!ReadFile(hChildPipeRead, str, sizeof(str), &nRead, &overlapped)) + do { - if (!GetOverlappedResultEx(hChildPipeRead, &overlapped, &nRead, (DWORD) timeout, TRUE)) - { - if (GetLastError() == ERROR_BROKEN_PIPE) - return "Child process closed its end (nothing to read)"; - CancelIo(hChildPipeRead); - TerminateProcess(piProcInfo.hProcess, 1); - return "GetOverlappedResultEx(hChildPipeRead) failed or timeout"; - } - } - while (nRead > 0) - { - ffStrbufAppendNS(buffer, nRead, str); if (!ReadFile(hChildPipeRead, str, sizeof(str), &nRead, &overlapped)) { - if (!GetOverlappedResult(hChildPipeRead, &overlapped, &nRead, TRUE)) + switch (GetLastError()) { - if (GetLastError() == ERROR_BROKEN_PIPE) - return NULL; + case ERROR_IO_PENDING: + if (!GetOverlappedResultEx(hChildPipeRead, &overlapped, &nRead, (DWORD) timeout, TRUE)) + { + if (GetLastError() == ERROR_BROKEN_PIPE) + return NULL; + CancelIo(hChildPipeRead); + TerminateProcess(piProcInfo.hProcess, 1); + return "GetOverlappedResultEx(hChildPipeRead) failed or timeout"; + } + break; + + case ERROR_BROKEN_PIPE: + return NULL; + + default: CancelIo(hChildPipeRead); - return "GetOverlappedResult(hChildPipeRead) failed"; + TerminateProcess(piProcInfo.hProcess, 1); + return "ReadFile(hChildPipeRead) failed"; } } - } + ffStrbufAppendNS(buffer, nRead, str); + } while (nRead > 0); return NULL; }