https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=26dafb54e385981ecb13991b6ab660ee86e5c82c
commit 26dafb54e385981ecb13991b6ab660ee86e5c82c Author: Takashi Yano <takashi.y...@nifty.ne.jp> Date: Mon Jul 14 10:40:08 2025 +0900 Cygwin: pty: TCIFLUSH also clears readahead buffer in the master Previously, TCIFLUSH flushed the pipe to_slave which transfers input from master to slave. However, this was not sufficiant. The master side holds input data before accept_input() in the read-ahead buffer. So, if input data before 'enter' key can be leaked into slave input after TCIFLUSH. With this patch, TCIFLUSH requests master to flush read-ahead buffer via master control pipe. To realize this, add cmd filed to pipe_request structure so that the flush request can be distinguished from existing pipe handle request. Addresses: https://cygwin.com/pipermail/cygwin/2025-July/258442.html Fixes: 41946df6111b (" (fhandler_tty_slave::tcflush): Implement input queue flushing by calling read with NULL buffer.") Reported-by: Christoph Reiter <reiter.christ...@gmail.com> Signed-off-by: Takashi Yano <takashi.y...@nifty.ne.jp> (cherry picked from commit 2aa41b516055ea9383508342706288deb3baf1f6) Diff: --- winsup/cygwin/fhandler/pty.cc | 31 ++++++++++++++++++++++++++----- winsup/cygwin/local_includes/fhandler.h | 1 + winsup/cygwin/release/3.6.4 | 3 +++ 3 files changed, 30 insertions(+), 5 deletions(-) diff --git a/winsup/cygwin/fhandler/pty.cc b/winsup/cygwin/fhandler/pty.cc index 3128b92da..36fddbbe9 100644 --- a/winsup/cygwin/fhandler/pty.cc +++ b/winsup/cygwin/fhandler/pty.cc @@ -42,7 +42,14 @@ extern "C" int sscanf (const char *, const char *, ...); } while (0) /* pty master control pipe messages */ +enum pipe_request_cmd { + GET_HANDLES, + FLUSH_INPUT, + QUIT +}; + struct pipe_request { + pipe_request_cmd cmd; DWORD pid; }; @@ -871,7 +878,7 @@ fhandler_pty_slave::open (int flags, mode_t) } else { - pipe_request req = { GetCurrentProcessId () }; + pipe_request req = { GET_HANDLES, GetCurrentProcessId () }; pipe_reply repl; DWORD len; @@ -1139,7 +1146,7 @@ fhandler_pty_slave::reset_switch_to_nat_pipe (void) __small_sprintf (pipe, "\\\\.\\pipe\\cygwin-%S-pty%d-master-ctl", &cygheap->installation_key, get_minor ()); - pipe_request req = { GetCurrentProcessId () }; + pipe_request req = { GET_HANDLES, GetCurrentProcessId () }; pipe_reply repl; DWORD len; if (!CallNamedPipe (pipe, &req, sizeof req, @@ -1597,6 +1604,14 @@ fhandler_pty_slave::tcflush (int queue) if (queue == TCIFLUSH || queue == TCIOFLUSH) { + char pipe[MAX_PATH]; + __small_sprintf (pipe, + "\\\\.\\pipe\\cygwin-%S-pty%d-master-ctl", + &cygheap->installation_key, get_minor ()); + pipe_request req = { FLUSH_INPUT, GetCurrentProcessId () }; + pipe_reply repl; + DWORD n; + CallNamedPipe (pipe, &req, sizeof req, &repl, sizeof repl, &n, 500); size_t len = UINT_MAX; read (NULL, len); ret = ((int) len) >= 0 ? 0 : -1; @@ -2020,7 +2035,7 @@ fhandler_pty_master::close (int flag) if (master_ctl && get_ttyp ()->master_pid == myself->pid) { char buf[MAX_PATH]; - pipe_request req = { (DWORD) -1 }; + pipe_request req = { QUIT, GetCurrentProcessId () }; pipe_reply repl; DWORD len; @@ -2521,13 +2536,18 @@ fhandler_pty_master::pty_master_thread (const master_thread_param_t *p) termios_printf ("RevertToSelf, %E"); goto reply; } - if (req.pid == (DWORD) -1) /* Request to finish thread. */ + if (req.cmd == QUIT) /* Request to finish thread. */ { /* Check if the requesting process is the master process itself. */ if (pid == GetCurrentProcessId ()) exit = true; goto reply; } + if (req.cmd == FLUSH_INPUT) + { + p->master->eat_readahead (-1); + goto reply; + } if (NT_SUCCESS (allow)) { client = OpenProcess (PROCESS_DUP_HANDLE, FALSE, pid); @@ -3780,6 +3800,7 @@ fhandler_pty_master::get_master_thread_param (master_thread_param_t *p) p->to_slave = get_output_handle (); p->master_ctl = master_ctl; p->input_available_event = input_available_event; + p->master = this; SetEvent (thread_param_copied_event); } @@ -3821,7 +3842,7 @@ fhandler_pty_slave::transfer_input (tty::xfer_dir dir, HANDLE from, tty *ttyp, __small_sprintf (pipe, "\\\\.\\pipe\\cygwin-%S-pty%d-master-ctl", &cygheap->installation_key, ttyp->get_minor ()); - pipe_request req = { GetCurrentProcessId () }; + pipe_request req = { GET_HANDLES, GetCurrentProcessId () }; pipe_reply repl; DWORD len; if (!CallNamedPipe (pipe, &req, sizeof req, diff --git a/winsup/cygwin/local_includes/fhandler.h b/winsup/cygwin/local_includes/fhandler.h index 3639a92a8..94f4bc552 100644 --- a/winsup/cygwin/local_includes/fhandler.h +++ b/winsup/cygwin/local_includes/fhandler.h @@ -2539,6 +2539,7 @@ public: HANDLE to_slave; HANDLE master_ctl; HANDLE input_available_event; + fhandler_pty_master *master; }; /* Parameter set for the static function pty_master_fwd_thread() */ struct master_fwd_thread_param_t { diff --git a/winsup/cygwin/release/3.6.4 b/winsup/cygwin/release/3.6.4 index 4338214a6..fbc61c811 100644 --- a/winsup/cygwin/release/3.6.4 +++ b/winsup/cygwin/release/3.6.4 @@ -28,3 +28,6 @@ Fixes: - Fix ACL operations on directories. Addresses: https://cygwin.com/pipermail/cygwin/2025-July/258433.html + +- Make TCIFLUSH also flush read-ahead data in the master. + Addresses: https://cygwin.com/pipermail/cygwin/2025-July/258442.html