[newlib-cygwin] Cygwin: pty: Fix input transfer when multiple non-cygwin apps exist

Takashi Yano tyan0@sourceware.org
Sun Mar 29 00:43:40 GMT 2026


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

commit b790b19dccb7b93f2ec78dbc8353f6da58776083
Author: Takashi Yano <takashi.yano@nifty.ne.jp>
Date:   Tue Mar 10 14:38:09 2026 +0900

    Cygwin: pty: Fix input transfer when multiple non-cygwin apps exist
    
    Cygwin maintains POSIX line discipline for its own processes:
    input goes through `line_edit()` before reaching the reading process.
    Native (non-Cygwin) processes must not receive line-edited input;
    they expect raw console input instead. To support both, the PTY keeps
    two independent pipe pairs for input: a "cyg" pipe for Cygwin processes
    and a "nat" pipe for native ones. The runtime switches between the two
    as the foreground process changes.
    
    The PTY tracks which process "owns" the nat pipe session via the
    shared-memory field `nat_pipe_owner_pid`. Only one process is the
    owner at any time. When `setup_for_non_cygwin_app()` finds that the
    current owner is still alive, it leaves ownership with that process
    rather than claiming it for the new one.
    
    This means that a Cygwin-spawned native process can go through
    `cleanup_for_non_cygwin_app()` without being the nat pipe owner.
    Before this fix, that cleanup called `transfer_input(to_cyg)`
    unconditionally, draining the pseudo console's input buffer even
    though another process still owned the session. Keystrokes that the
    user had typed were moved to the cyg pipe prematurely, so the actual
    owner found an empty console input buffer and appeared to lose all
    input.
    
    When looking for the next owner of the console in
    `cleanup_for_non_cygwin_app()` (via `get_winpid_to_hand_over()`),
    and when transferring the input back to the cyg pipe, guard both with
    a `nat_pipe_owner_self()` check so that only the actual owner performs
    these operations. Non-owner processes skip straight to detaching from
    the pseudo console without disturbing the input buffer.
    
    Fixes: f9542a2e8e75 ("Cygwin: pty: Re-fix the last bug regarding nat-pipe.")
    Signed-off-by: Takashi Yano <takashi.yano@nifty.ne.jp>
    Reviewed-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>

Diff:
---
 winsup/cygwin/fhandler/pty.cc | 21 ++++++++++++---------
 1 file changed, 12 insertions(+), 9 deletions(-)

diff --git a/winsup/cygwin/fhandler/pty.cc b/winsup/cygwin/fhandler/pty.cc
index 8c290eb59..fbc6152e5 100644
--- a/winsup/cygwin/fhandler/pty.cc
+++ b/winsup/cygwin/fhandler/pty.cc
@@ -4180,16 +4180,19 @@ fhandler_pty_slave::cleanup_for_non_cygwin_app (handle_set_t *p, tty *ttyp,
 {
   ttyp->wait_fwd ();
   WaitForSingleObject (p->pipe_sw_mutex, INFINITE);
-  DWORD switch_to = get_winpid_to_hand_over (ttyp, force_switch_to);
-  if ((!switch_to && (ttyp->pcon_activated || stdin_is_ptys))
-      && ttyp->pty_input_state_eq (tty::to_nat))
+  if (nat_pipe_owner_self (ttyp->nat_pipe_owner_pid))
     {
-      WaitForSingleObject (p->input_mutex, mutex_timeout);
-      acquire_attach_mutex (mutex_timeout);
-      transfer_input (tty::to_cyg, p->from_master_nat, ttyp,
-		      p->input_available_event);
-      release_attach_mutex ();
-      ReleaseMutex (p->input_mutex);
+      DWORD switch_to = get_winpid_to_hand_over (ttyp, force_switch_to);
+      if ((!switch_to && (ttyp->pcon_activated || stdin_is_ptys))
+	  && ttyp->pty_input_state_eq (tty::to_nat))
+	{
+	  WaitForSingleObject (p->input_mutex, mutex_timeout);
+	  acquire_attach_mutex (mutex_timeout);
+	  transfer_input (tty::to_cyg, p->from_master_nat, ttyp,
+			  p->input_available_event);
+	  release_attach_mutex ();
+	  ReleaseMutex (p->input_mutex);
+	}
     }
   if (ttyp->pcon_activated)
     close_pseudoconsole (ttyp, force_switch_to);


More information about the Cygwin-cvs mailing list