[newlib-cygwin] Cygwin: pty: Fix input transfer when multiple non-cygwin apps exist
Takashi Yano via Cygwin-cvs <[email protected]> Sun, 29 Mar 2026 00:43:40 +0000 (GMT)
| Newsgroups | gmane.os.cygwin.cvs |
|---|---|
| Message-ID | <[email protected]> |
https://sourceware.org/git/gitweb.cgi?p=3Dnewlib-cygwin.git;h=3Db790b19dccb= 7b93f2ec78dbc8353f6da58776083 commit b790b19dccb7b93f2ec78dbc8353f6da58776083 Author: Takashi Yano <[email protected]> Date: Tue Mar 10 14:38:09 2026 +0900 Cygwin: pty: Fix input transfer when multiple non-cygwin apps exist =20 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. =20 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. =20 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. =20 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. =20 Fixes: f9542a2e8e75 ("Cygwin: pty: Re-fix the last bug regarding nat-pi= pe.") Signed-off-by: Takashi Yano <[email protected]> Reviewed-by: Johannes Schindelin <[email protected]> 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 (han= dle_set_t *p, tty *ttyp, { ttyp->wait_fwd (); WaitForSingleObject (p->pipe_sw_mutex, INFINITE); - DWORD switch_to =3D 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 =3D 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);