It is possible for `NtQueryInformationFile()` to report a 0-length
`InboundQuota` when obtaining `FilePipeLocalInformation`. This seems to
be the case e.g. when a pipe was created on the other side and its quota
information is not available on the client side.

This can lead to a situation where the `avail` variable is set to 0, and
since that is used to cap the number of bytes to send, a 0-length write.
Which hangs forever.

This was observed in the MSYS2 project when building GIMP, and reduced
to a simple test case where a MINGW `ninja.exe` tries to call an MSYS
`bison.exe` and the error message (saying that `bison` wants to have
some input) is not even shown.

Since the minimal pipe buffer size is 4k, let's ensure that it is at
least that, even when `InboundQuota` reports 0.

This fixes https://github.com/msys2/msys2-runtime/issues/270

Fixes: cbfaeba4f7 (Cygwin: pipe: Fix incorrect write length in raw_write())
Helped-by: Corinna Vinschen <cori...@vinschen.de>
Signed-off-by: Johannes Schindelin <johannes.schinde...@gmx.de>
---
Published-As: 
https://github.com/dscho/msys2-runtime/releases/tag/fix-ninja-hang-v1
Fetch-It-Via: git fetch https://github.com/dscho/msys2-runtime fix-ninja-hang-v1

 As per Corinna's request on IRC (thank you _so much_ for your invaluable
 help!), I have specifically verified that this does not regress on
 691afb1f6d (Cygwin: pipe: Fix 'lost connection' issue in scp, 2025-03-05)
 by running this in a loop:

   echo put /tmp/big.file | ./sftp -v -D ./sftp-server sftp://localhost

 (prior to running this on the patched runtime, I verified that it
 reproduces after reverting 691afb1f6d; It took 79 iterations to lose the
 connection, but in the end it did! And with that revert dropped and with
 this here patch applied, it survived 400 iterations without losing the
 connection.)

 winsup/cygwin/fhandler/pipe.cc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/winsup/cygwin/fhandler/pipe.cc b/winsup/cygwin/fhandler/pipe.cc
index 3537180024..92fc09de4a 100644
--- a/winsup/cygwin/fhandler/pipe.cc
+++ b/winsup/cygwin/fhandler/pipe.cc
@@ -1158,7 +1158,7 @@ fhandler_pipe::set_pipe_buf_size ()
   status = NtQueryInformationFile (get_handle (), &io, &fpli, sizeof fpli,
                                   FilePipeLocalInformation);
   if (NT_SUCCESS (status))
-    pipe_buf_size = fpli.InboundQuota;
+    pipe_buf_size = fpli.InboundQuota < PIPE_BUF ? PIPE_BUF : 
fpli.InboundQuota;
 }

 int

base-commit: c1770e171505eb674626c2b7abf3403e6b4b7b79
--
2.49.0.windows.1

Reply via email to