https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=236e865e204cc4d6acb100fe6cbe91ff0af8852d

commit 236e865e204cc4d6acb100fe6cbe91ff0af8852d
Author: Takashi Yano <takashi.y...@nifty.ne.jp>
Date:   Mon Mar 31 22:09:17 2025 +0900

    Cygwin: pipe: Add workaround for native ninja
    
    Native (non-cygwin) ninja creates pipe with size == 0, and starts
    cygwin process with that pipe. This causes infinite loop in the
    fhandler_fifo_pipe::raw_write(). Ideally, the pipe implementation
    in cygwin could work even with pipe size == 0, however, it seems
    impossible due to:
    
    (1) select() does not work for that pipe because PeekNamedPipe()
        always returns 0. Read side is ready to read only when the
        write side is about to write, but there is no way to know that.
    (2) The cause of the problem:
        https://cygwin.com/pipermail/cygwin/2025-January/257143.html
        cannot be avoidable. To avoid CancelIo() problem, the patch
        https://cygwin.com/pipermail/cygwin-patches/2025q1/013451.html
        restricts the data size less than the current pipe space.
        However, if pipe size is zero this is impossible.
    
    This patch adds just a workaround for native ninja that avoid
    infinite loop in raw_write().
    
    Addresses: https://github.com/msys2/msys2-runtime/issues/270
    Reported-by: Christoph Reiter <reiter.christ...@gmail.com>
    Co-authored-by: Johannes Schindelin <johannes.schinde...@gmx.de>
    Reviewed-by: Corinna Vinschen <cori...@vinschen.de>
    Signed-off-by: Takashi Yano <takashi.y...@nifty.ne.jp>

Diff:
---
 winsup/cygwin/fhandler/pipe.cc | 5 +++++
 winsup/cygwin/select.cc        | 4 +++-
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/winsup/cygwin/fhandler/pipe.cc b/winsup/cygwin/fhandler/pipe.cc
index ac8bbe7d6..e35d523bb 100644
--- a/winsup/cygwin/fhandler/pipe.cc
+++ b/winsup/cygwin/fhandler/pipe.cc
@@ -455,6 +455,11 @@ fhandler_pipe_fifo::raw_write (const void *ptr, size_t len)
   ssize_t avail = pipe_buf_size;
   bool real_non_blocking_mode = false;
 
+  /* Workaround for native ninja. Native ninja creates pipe with size == 0,
+     and starts cygwin process with that pipe. */
+  if (avail == 0)
+    avail = PIPE_BUF;
+
   if (pipe_mtx) /* pipe_mtx is NULL in the fifo case */
     {
       DWORD timeout = is_nonblocking () ? 0 : INFINITE;
diff --git a/winsup/cygwin/select.cc b/winsup/cygwin/select.cc
index 422c8e830..bb141b065 100644
--- a/winsup/cygwin/select.cc
+++ b/winsup/cygwin/select.cc
@@ -670,7 +670,9 @@ pipe_data_available (int fd, fhandler_base *fh, HANDLE h, 
int mode)
                           fpli.WriteQuotaAvailable);
          return fpli.WriteQuotaAvailable;
        }
-      /* TODO: Buffer really full or non-Cygwin reader? */
+      return PIPE_BUF; /* Workaround for native ninja. Native ninja creates
+                         pipe with size == 0, and starts cygwin process
+                         with that pipe. */
     }
   else if (fpli.ReadDataAvailable)
     {

Reply via email to