[PATCH v4] Cygwin: pty: Do not transfer input to nat-pipe while masked
Takashi Yano <[email protected]> Wed, 8 Jul 2026 13:54:04 +0900
| Newsgroups | gmane.os.cygwin.patches |
|---|---|
| Message-ID | <[email protected]> |
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.
This patch prevent the pipe state from changing to nat-pipe state if
some cygwin process is reading input from the cyg-pipe.
Fixes: f20641789427 ("Cygwin: pty: Reduce unecessary input transfer.")
Signed-off-by: Takashi Yano <[email protected]>
Reviewed-by: Johannes Schindelin <[email protected]>
---
v2: Release all masks owned by myself on cleanup()
v3: Reverts the change that made num_reader and slave_reading shared
v4: Correct what mutex shoud be acquired in mask_switch_to_nat_pipe()
winsup/cygwin/fhandler/pty.cc | 27 ++++++++++++++++++++++-----
1 file changed, 22 insertions(+), 5 deletions(-)
diff --git a/winsup/cygwin/fhandler/pty.cc b/winsup/cygwin/fhandler/pty.cc
index ca85ae679..1b453a499 100644
--- a/winsup/cygwin/fhandler/pty.cc
+++ b/winsup/cygwin/fhandler/pty.cc
@@ -1282,6 +1282,10 @@ fhandler_pty_slave::open_setup (int flags)
void
fhandler_pty_slave::cleanup ()
{
+ fhandler_pty_slave *arch = (fhandler_pty_slave *) archetype ? : this;
+ while (arch->num_reader)
+ mask_switch_to_nat_pipe (false, false);
+
if (get_ttyp ()->pcon_activated && get_ttyp ()->getpgid () == myself->pgid)
req_fixup_pcon_state ();
@@ -1543,19 +1547,20 @@ fhandler_pty_slave::write (const void *ptr, size_t len)
void
fhandler_pty_slave::mask_switch_to_nat_pipe (bool mask, bool xfer)
{
+ WaitForSingleObject (input_mutex, mutex_timeout);
char name[MAX_PATH];
shared_name (name, TTY_SLAVE_READING, get_minor ());
HANDLE masked = OpenEvent (READ_CONTROL, FALSE, name);
CloseHandle (masked);
- WaitForSingleObject (input_mutex, mutex_timeout);
+ fhandler_pty_slave *arch = (fhandler_pty_slave *) archetype ? : this;
if (mask)
{
- if (InterlockedIncrement (&num_reader) == 1)
- slave_reading = CreateEvent (&sec_none_nih, TRUE, FALSE, name);
+ if (InterlockedIncrement (&arch->num_reader) == 1)
+ arch->slave_reading = CreateEvent (&sec_none_nih, TRUE, FALSE, name);
}
- else if (InterlockedDecrement (&num_reader) == 0)
- CloseHandle (slave_reading);
+ else if (InterlockedDecrement (&arch->num_reader) == 0)
+ CloseHandle (arch->slave_reading);
if (!!masked != mask && xfer && get_ttyp ()->switch_to_nat_pipe)
{
@@ -4460,6 +4465,18 @@ fhandler_pty_slave::transfer_input (tty::xfer_dir dir, HANDLE from, tty *ttyp,
HANDLE input_available_event,
HANDLE input_transferred_to_cyg)
{
+ if (dir == tty::to_nat)
+ {
+ char name[MAX_PATH];
+ shared_name (name, TTY_SLAVE_READING, ttyp->get_minor ());
+ HANDLE masked = 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 == tty::to_nat)
to = ttyp->to_slave_nat ();
--
2.51.0