[newlib-cygwin/cygwin-3_6-branch] Cygwin: pty: Do not transfer input to nat-pipe while masked

Takashi Yano via Cygwin-cvs <[email protected]> Wed, 8 Jul 2026 18:09:09 +0000 (GMT)
Newsgroups gmane.os.cygwin.cvs
Message-ID <[email protected]>
https://sourceware.org/git/gitweb.cgi?p=3Dnewlib-cygwin.git;h=3Dfa1e820cab7=
41c4e38839cf9613b4eee4d9e4281

commit fa1e820cab741c4e38839cf9613b4eee4d9e4281
Author: Takashi Yano <[email protected]>
Date:   Tue Jun 30 14:12:38 2026 +0900

    Cygwin: pty: Do not transfer input to nat-pipe while masked
   =20
    On the command "cat | non-cygwin-app", `cat` sometimes fails to read
    key input. This happens when `cat` starts to read input before `non-
    cygwin-app` configures pseudo console. This is because pipe state is
    switched to nat-pipe when pseudo console is configured.
   =20
    This patch prevent the pipe state from changing to nat-pipe state if
    some cygwin process is reading input from the cyg-pipe.
   =20
    Fixes: f20641789427 ("Cygwin: pty: Reduce unecessary input transfer.")
    Signed-off-by: Takashi Yano <[email protected]>
    Reviewed-by: Johannes Schindelin <[email protected]>
    (cherry picked from commit 4c0fc56cad9d39afbacebcc58d2174d1af131b2c)

Diff:
---
 winsup/cygwin/fhandler/pty.cc | 30 +++++++++++++++++++++++++-----
 1 file changed, 25 insertions(+), 5 deletions(-)

diff --git a/winsup/cygwin/fhandler/pty.cc b/winsup/cygwin/fhandler/pty.cc
index d27ba4e59..387bc03f3 100644
--- a/winsup/cygwin/fhandler/pty.cc
+++ b/winsup/cygwin/fhandler/pty.cc
@@ -998,6 +998,10 @@ fhandler_pty_slave::open_setup (int flags)
 void
 fhandler_pty_slave::cleanup ()
 {
+  fhandler_pty_slave *arch =3D (fhandler_pty_slave *) archetype ? : this;
+  while (arch->num_reader)
+    mask_switch_to_nat_pipe (false, false);
+
   /* This used to always call fhandler_pty_common::close when we were exec=
ing
      but that caused multiple closes of the handles associated with this p=
ty.
      Since close_all_files is not called until after the cygwin process has
@@ -1255,19 +1259,23 @@ fhandler_pty_slave::write (const void *ptr, size_t =
len)
 void
 fhandler_pty_slave::mask_switch_to_nat_pipe (bool mask, bool xfer)
 {
+  /* This input_mutex guard works as expected only because every
+     caller of transfer_input() holds input_mutex. This is a non-
+     local precondition. */
+  WaitForSingleObject (input_mutex, mutex_timeout);
   char name[MAX_PATH];
   shared_name (name, TTY_SLAVE_READING, get_minor ());
   HANDLE masked =3D OpenEvent (READ_CONTROL, FALSE, name);
   CloseHandle (masked);
=20
-  WaitForSingleObject (input_mutex, mutex_timeout);
+  fhandler_pty_slave *arch =3D (fhandler_pty_slave *) archetype ? : this;
   if (mask)
     {
-      if (InterlockedIncrement (&num_reader) =3D=3D 1)
-	slave_reading =3D CreateEvent (&sec_none_nih, TRUE, FALSE, name);
+      if (InterlockedIncrement (&arch->num_reader) =3D=3D 1)
+	arch->slave_reading =3D CreateEvent (&sec_none_nih, TRUE, FALSE, name);
     }
-  else if (InterlockedDecrement (&num_reader) =3D=3D 0)
-    CloseHandle (slave_reading);
+  else if (InterlockedDecrement (&arch->num_reader) =3D=3D 0)
+    CloseHandle (arch->slave_reading);
=20
   if (!!masked !=3D mask && xfer && get_ttyp ()->switch_to_nat_pipe)
     {
@@ -4120,6 +4128,18 @@ fhandler_pty_slave::transfer_input (tty::xfer_dir di=
r, HANDLE from, tty *ttyp,
 				    HANDLE input_available_event,
 				    HANDLE input_transferred_to_cyg)
 {
+  if (dir =3D=3D tty::to_nat)
+    {
+      char name[MAX_PATH];
+      shared_name (name, TTY_SLAVE_READING, ttyp->get_minor ());
+      HANDLE masked =3D OpenEvent (READ_CONTROL, FALSE, name);
+      CloseHandle (masked);
+      if (masked)
+	/* Cygwin process is reading cyg-pipe.
+	   Do not transfer input to nat-pipe. */
+	return;
+    }
+
   HANDLE to;
   if (dir =3D=3D tty::to_nat)
     to =3D ttyp->to_slave_nat ();