[PATCH] Cygwin: pipe: Restore blocking mode of read pipe on close()
Takashi Yano
takashi.yano@nifty.ne.jp
Fri Aug 30 14:15:44 GMT 2024
If a cygwin app is executed from a non-cygwin app and the cygwin
app exits, read pipe remains on non-blocking mode because of the
commit fc691d0246b9. Due to this behaviour, the non-cygwin app
cannot read the pipe correctly after that. With this patch, the
blocking mode of the read pipe is stored into was_blocking_read_pipe
on set_pipe_non_blocking() when the cygwin app starts and restored
on close().
Addresses: https://github.com/git-for-windows/git/issues/5115
Fixes: fc691d0246b9 ("Cygwin: pipe: Make sure to set read pipe non-blocking for cygwin apps.");
Reported-by: isaacag, Johannes Schindelin <Johannes.Schindelin@gmx.de>
Reviewed-by:
Signed-off-by: Takashi Yano <takashi.yano@nifty.ne.jp>
---
winsup/cygwin/fhandler/pipe.cc | 12 ++++++++++++
winsup/cygwin/local_includes/fhandler.h | 1 +
2 files changed, 13 insertions(+)
diff --git a/winsup/cygwin/fhandler/pipe.cc b/winsup/cygwin/fhandler/pipe.cc
index 852076ccc..5c760d704 100644
--- a/winsup/cygwin/fhandler/pipe.cc
+++ b/winsup/cygwin/fhandler/pipe.cc
@@ -55,6 +55,15 @@ fhandler_pipe::set_pipe_non_blocking (bool nonblocking)
IO_STATUS_BLOCK io;
FILE_PIPE_INFORMATION fpi;
+ if (get_device () == FH_PIPER && nonblocking && !was_blocking_read_pipe)
+ {
+ status = NtQueryInformationFile (get_handle (), &io, &fpi, sizeof fpi,
+ FilePipeInformation);
+ if (NT_SUCCESS (status))
+ was_blocking_read_pipe =
+ (fpi.CompletionMode == FILE_PIPE_QUEUE_OPERATION);
+ }
+
fpi.ReadMode = FILE_PIPE_BYTE_STREAM_MODE;
fpi.CompletionMode = nonblocking ? FILE_PIPE_COMPLETE_OPERATION
: FILE_PIPE_QUEUE_OPERATION;
@@ -95,6 +104,7 @@ fhandler_pipe::init (HANDLE f, DWORD a, mode_t mode, int64_t uniq_id)
even with FILE_SYNCHRONOUS_IO_NONALERT. */
set_pipe_non_blocking (get_device () == FH_PIPER ?
true : is_nonblocking ());
+ was_blocking_read_pipe = false;
/* Store pipe name to path_conv pc for query_hdl check */
if (get_dev () == FH_PIPEW)
@@ -734,6 +744,8 @@ fhandler_pipe::close ()
CloseHandle (query_hdl);
if (query_hdl_close_req_evt)
CloseHandle (query_hdl_close_req_evt);
+ if (was_blocking_read_pipe)
+ set_pipe_non_blocking (false);
int ret = fhandler_base::close ();
ReleaseMutex (hdl_cnt_mtx);
CloseHandle (hdl_cnt_mtx);
diff --git a/winsup/cygwin/local_includes/fhandler.h b/winsup/cygwin/local_includes/fhandler.h
index 8b02a2b1b..16c39b55b 100644
--- a/winsup/cygwin/local_includes/fhandler.h
+++ b/winsup/cygwin/local_includes/fhandler.h
@@ -1216,6 +1216,7 @@ private:
HANDLE query_hdl_proc;
HANDLE query_hdl_value;
HANDLE query_hdl_close_req_evt;
+ bool was_blocking_read_pipe;
void release_select_sem (const char *);
HANDLE get_query_hdl_per_process (OBJECT_NAME_INFORMATION *);
public:
--
2.45.1
More information about the Cygwin-patches
mailing list