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 <[email protected]> Reviewed-by: Signed-off-by: Takashi Yano <[email protected]> --- 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
