[PATCH v2] Cygwin: pty: Do not transfer input to nat-pipe while masked
Takashi Yano <[email protected]> Tue, 30 Jun 2026 17:14:29 +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:
---
v2: Release all masks owned by myself on cleanup()
winsup/cygwin/fhandler/pty.cc | 33 +++++++++++++++++++++----
winsup/cygwin/local_includes/fhandler.h | 3 +--
winsup/cygwin/local_includes/tty.h | 2 ++
3 files changed, 31 insertions(+), 7 deletions(-)
diff --git a/winsup/cygwin/fhandler/pty.cc b/winsup/cygwin/fhandler/pty.cc
index 35e320507..54cd64a47 100644
--- a/winsup/cygwin/fhandler/pty.cc
+++ b/winsup/cygwin/fhandler/pty.cc
@@ -951,7 +951,7 @@ out:
fhandler_pty_slave::fhandler_pty_slave (int unit, dev_t via)
: fhandler_pty_common (), inuse (NULL), output_handle_nat (NULL),
- io_handle_nat (NULL), slave_reading (NULL), num_reader (0)
+ io_handle_nat (NULL), masked_cnt (0)
{
dev_referred_via = via;
if (unit >= 0)
@@ -1230,6 +1230,10 @@ fhandler_pty_slave::open_setup (int flags)
void
fhandler_pty_slave::cleanup ()
{
+ fhandler_pty_slave *arch = (fhandler_pty_slave *) archetype ? : this;
+ while (arch->masked_cnt)
+ mask_switch_to_nat_pipe (false, false);
+
if (get_ttyp ()->pcon_activated && get_ttyp ()->getpgid () == myself->pgid)
req_fixup_pcon_state ();
@@ -1499,11 +1503,18 @@ fhandler_pty_slave::mask_switch_to_nat_pipe (bool mask, bool xfer)
WaitForSingleObject (input_mutex, mutex_timeout);
if (mask)
{
- if (InterlockedIncrement (&num_reader) == 1)
- slave_reading = CreateEvent (&sec_none_nih, TRUE, FALSE, name);
+ if (InterlockedIncrement (&get_ttyp ()->num_reader) == 1)
+ get_ttyp ()->slave_reading =
+ CreateEvent (&sec_none_nih, TRUE, FALSE, name);
}
- else if (InterlockedDecrement (&num_reader) == 0)
- CloseHandle (slave_reading);
+ else if (InterlockedDecrement (&get_ttyp ()->num_reader) == 0)
+ CloseHandle (get_ttyp ()->slave_reading);
+
+ fhandler_pty_slave *arch = (fhandler_pty_slave *) archetype ? : this;
+ if (mask)
+ InterlockedIncrement (&arch->masked_cnt);
+ else
+ InterlockedDecrement (&arch->masked_cnt);
if (!!masked != mask && xfer && get_ttyp ()->switch_to_nat_pipe)
{
@@ -4401,6 +4412,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 ();
diff --git a/winsup/cygwin/local_includes/fhandler.h b/winsup/cygwin/local_includes/fhandler.h
index 8e9cbef4b..d8b6f5950 100644
--- a/winsup/cygwin/local_includes/fhandler.h
+++ b/winsup/cygwin/local_includes/fhandler.h
@@ -2442,8 +2442,7 @@ class fhandler_pty_slave: public fhandler_pty_common
{
HANDLE inuse; // used to indicate that a tty is in use
HANDLE output_handle_nat, io_handle_nat;
- HANDLE slave_reading;
- LONG num_reader;
+ LONG masked_cnt;
/* Helper functions for fchmod and fchown. */
bool fch_open_handles (bool chown);
diff --git a/winsup/cygwin/local_includes/tty.h b/winsup/cygwin/local_includes/tty.h
index c5102eb81..407565ce9 100644
--- a/winsup/cygwin/local_includes/tty.h
+++ b/winsup/cygwin/local_includes/tty.h
@@ -146,6 +146,8 @@ private:
bool discard_input;
bool stop_fwd_thread;
bool req_fixup_pcon_cur_pos;
+ HANDLE slave_reading;
+ LONG num_reader;
public:
HANDLE from_master_nat () const { return _from_master_nat; }
--
2.51.0