[PATCH 2/4] Cygwin: pty: Remove pcon_start readahead flush that displaces readline data
Johannes Schindelin via GitGitGadget
gitgitgadget@gmail.com
Mon Mar 2 14:24:38 GMT 2026
From: Johannes Schindelin <johannes.schindelin@gmx.de>
After the previous commit addressed the worst data-stealing code
path, roughly one in five test iterations still shows a stray
character. Another transfer code path in master::write() is
responsible.
When a native process becomes the PTY foreground, the pseudo console
must be initialized. During this "pcon_start" phase, master::write()
enters a polling loop that feeds keystrokes to the nascent pseudo
console. When the loop completes (pcon_start becomes false), there
was a block of code that:
1. Flushed the master's readahead buffer via accept_input()
2. Called transfer_input(to_nat) to move all cyg pipe data
to the nat pipe
The intent was to preserve typeahead: characters typed during pcon
initialization should eventually reach the native process. But
during pseudo console oscillation (the rapid pcon on/off cycles
described in the previous commit), this fires on every pcon
re-initialization -- and the "typeahead" it transfers includes
readline's entire editing buffer.
Worse, if the terminal emulator was mid-way through sending a rapid
editing sequence like "XY<BS><BS>" (type two characters, then erase
them with backspace), the readahead flush fires after buffering "X"
but before the backspaces arrive. The orphaned "X" gets pushed to
the cyg pipe via accept_input(), where readline sees it as genuine
input -- producing a stray character that the user never intended.
Remove the accept_input() and transfer_input() calls entirely.
Keep `pcon_start_pid = 0`, which marks the end of initialization.
The readahead data belongs to the Cygwin process (bash is in
canonical mode during command entry) and will be delivered naturally
when line_edit() encounters a newline or when readline switches the
terminal to raw mode after the foreground command exits. The
setpgid_aux() code path in the slave process still handles the
steady-state cyg-to-nat transfer at process-group boundaries.
Combined with the previous commit, Git for Windows' AutoHotKey-based
UI tests now pass cleanly in the vast majority of iterations.
Regression note: the removed code was motivated by a 2020 bug report
about lost typeahead with native processes:
https://inbox.sourceware.org/cygwin/7e3d947e-b178-30a3-589f-b48e6003fbb3@googlemail.com/
Since the pcon_start window is brief (a few milliseconds) and
setpgid_aux() handles the steady-state transfer, the risk of
typeahead loss is low.
Addresses: https://github.com/git-for-windows/git/issues/5632
Fixes: 10d083c745dd ("Cygwin: pty: Inherit typeahead data between two input pipes.")
Fixes: f20641789427 ("Cygwin: pty: Reduce unecessary input transfer.")
Assisted-by: Claude Opus 4.6
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
winsup/cygwin/fhandler/pty.cc | 15 ---------------
1 file changed, 15 deletions(-)
diff --git a/winsup/cygwin/fhandler/pty.cc b/winsup/cygwin/fhandler/pty.cc
index f7db43b9d..2450057c1 100644
--- a/winsup/cygwin/fhandler/pty.cc
+++ b/winsup/cygwin/fhandler/pty.cc
@@ -2186,21 +2186,6 @@ fhandler_pty_master::write (const void *ptr, size_t len)
if (!get_ttyp ()->pcon_start)
{ /* Pseudo console initialization has been done in above code. */
pinfo pp (get_ttyp ()->pcon_start_pid);
- if (get_ttyp ()->switch_to_nat_pipe
- && get_ttyp ()->pty_input_state_eq (tty::to_cyg))
- {
- /* This accept_input() call is needed in order to transfer input
- which is not accepted yet to non-cygwin pipe. */
- WaitForSingleObject (input_mutex, mutex_timeout);
- if (get_readahead_valid ())
- accept_input ();
- acquire_attach_mutex (mutex_timeout);
- fhandler_pty_slave::transfer_input (tty::to_nat, from_master,
- get_ttyp (),
- input_available_event);
- release_attach_mutex ();
- ReleaseMutex (input_mutex);
- }
get_ttyp ()->pcon_start_pid = 0;
}
--
cygwingitgadget
More information about the Cygwin-patches
mailing list