Skip to content

Commit 26dafb5

Browse files
committed
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: 41946df (" (fhandler_tty_slave::tcflush): Implement input queue flushing by calling read with NULL buffer.") Reported-by: Christoph Reiter <[email protected]> Signed-off-by: Takashi Yano <[email protected]> (cherry picked from commit 2aa41b516055ea9383508342706288deb3baf1f6)
1 parent ae6683e commit 26dafb5

File tree

3 files changed

+30
-5
lines changed

3 files changed

+30
-5
lines changed

winsup/cygwin/fhandler/pty.cc

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,14 @@ extern "C" int sscanf (const char *, const char *, ...);
4242
} while (0)
4343

4444
/* pty master control pipe messages */
45+
enum pipe_request_cmd {
46+
GET_HANDLES,
47+
FLUSH_INPUT,
48+
QUIT
49+
};
50+
4551
struct pipe_request {
52+
pipe_request_cmd cmd;
4653
DWORD pid;
4754
};
4855

@@ -871,7 +878,7 @@ fhandler_pty_slave::open (int flags, mode_t)
871878
}
872879
else
873880
{
874-
pipe_request req = { GetCurrentProcessId () };
881+
pipe_request req = { GET_HANDLES, GetCurrentProcessId () };
875882
pipe_reply repl;
876883
DWORD len;
877884

@@ -1139,7 +1146,7 @@ fhandler_pty_slave::reset_switch_to_nat_pipe (void)
11391146
__small_sprintf (pipe,
11401147
"\\\\.\\pipe\\cygwin-%S-pty%d-master-ctl",
11411148
&cygheap->installation_key, get_minor ());
1142-
pipe_request req = { GetCurrentProcessId () };
1149+
pipe_request req = { GET_HANDLES, GetCurrentProcessId () };
11431150
pipe_reply repl;
11441151
DWORD len;
11451152
if (!CallNamedPipe (pipe, &req, sizeof req,
@@ -1597,6 +1604,14 @@ fhandler_pty_slave::tcflush (int queue)
15971604

15981605
if (queue == TCIFLUSH || queue == TCIOFLUSH)
15991606
{
1607+
char pipe[MAX_PATH];
1608+
__small_sprintf (pipe,
1609+
"\\\\.\\pipe\\cygwin-%S-pty%d-master-ctl",
1610+
&cygheap->installation_key, get_minor ());
1611+
pipe_request req = { FLUSH_INPUT, GetCurrentProcessId () };
1612+
pipe_reply repl;
1613+
DWORD n;
1614+
CallNamedPipe (pipe, &req, sizeof req, &repl, sizeof repl, &n, 500);
16001615
size_t len = UINT_MAX;
16011616
read (NULL, len);
16021617
ret = ((int) len) >= 0 ? 0 : -1;
@@ -2020,7 +2035,7 @@ fhandler_pty_master::close (int flag)
20202035
if (master_ctl && get_ttyp ()->master_pid == myself->pid)
20212036
{
20222037
char buf[MAX_PATH];
2023-
pipe_request req = { (DWORD) -1 };
2038+
pipe_request req = { QUIT, GetCurrentProcessId () };
20242039
pipe_reply repl;
20252040
DWORD len;
20262041

@@ -2521,13 +2536,18 @@ fhandler_pty_master::pty_master_thread (const master_thread_param_t *p)
25212536
termios_printf ("RevertToSelf, %E");
25222537
goto reply;
25232538
}
2524-
if (req.pid == (DWORD) -1) /* Request to finish thread. */
2539+
if (req.cmd == QUIT) /* Request to finish thread. */
25252540
{
25262541
/* Check if the requesting process is the master process itself. */
25272542
if (pid == GetCurrentProcessId ())
25282543
exit = true;
25292544
goto reply;
25302545
}
2546+
if (req.cmd == FLUSH_INPUT)
2547+
{
2548+
p->master->eat_readahead (-1);
2549+
goto reply;
2550+
}
25312551
if (NT_SUCCESS (allow))
25322552
{
25332553
client = OpenProcess (PROCESS_DUP_HANDLE, FALSE, pid);
@@ -3780,6 +3800,7 @@ fhandler_pty_master::get_master_thread_param (master_thread_param_t *p)
37803800
p->to_slave = get_output_handle ();
37813801
p->master_ctl = master_ctl;
37823802
p->input_available_event = input_available_event;
3803+
p->master = this;
37833804
SetEvent (thread_param_copied_event);
37843805
}
37853806

@@ -3821,7 +3842,7 @@ fhandler_pty_slave::transfer_input (tty::xfer_dir dir, HANDLE from, tty *ttyp,
38213842
__small_sprintf (pipe,
38223843
"\\\\.\\pipe\\cygwin-%S-pty%d-master-ctl",
38233844
&cygheap->installation_key, ttyp->get_minor ());
3824-
pipe_request req = { GetCurrentProcessId () };
3845+
pipe_request req = { GET_HANDLES, GetCurrentProcessId () };
38253846
pipe_reply repl;
38263847
DWORD len;
38273848
if (!CallNamedPipe (pipe, &req, sizeof req,

winsup/cygwin/local_includes/fhandler.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2539,6 +2539,7 @@ class fhandler_pty_master: public fhandler_pty_common
25392539
HANDLE to_slave;
25402540
HANDLE master_ctl;
25412541
HANDLE input_available_event;
2542+
fhandler_pty_master *master;
25422543
};
25432544
/* Parameter set for the static function pty_master_fwd_thread() */
25442545
struct master_fwd_thread_param_t {

winsup/cygwin/release/3.6.4

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,6 @@ Fixes:
2828

2929
- Fix ACL operations on directories.
3030
Addresses: https://cygwin.com/pipermail/cygwin/2025-July/258433.html
31+
32+
- Make TCIFLUSH also flush read-ahead data in the master.
33+
Addresses: https://cygwin.com/pipermail/cygwin/2025-July/258442.html

0 commit comments

Comments
 (0)