https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=7b5fb35e376cfab42335291008758a2a64ff66b1
commit 7b5fb35e376cfab42335291008758a2a64ff66b1 Author: Takashi Yano <takashi.y...@nifty.ne.jp> Date: Sat Aug 30 11:39:39 2025 +0900 Cygwin: pty: Fix FLUSHO handling Previsouly, FLUSHO did not work correctly. 1) Even when FLUSHO is set, read() returns with undesired data in the pipe if select() is called in advance. 2) FLUSHO is toggled even in the case pseudo console enabled. Due to these problems, read data in the pty master was partially lost when Ctrl-O is pressed. With this patch, the mask_flusho flag, that was introduced by the commit 9677efcf005a and caused the issue 1), has been dropped and select() and read() for pty master discards the pipe data instead if FLUSHO flag is set. In addition, FLUSHO handling in the case pseudo console activated is disabled. Addresses: https://cygwin.com/pipermail/cygwin/2025-August/258717.html Fixes: 2cab4d0bb4af ("Cygwin: pty, console: Refactor the code processing special keys.") Fixes: 9677efcf005a ("Cygwin: pty: Make FLUSHO and Ctrl-O work.") Reported-by: Reported-by: Thomas Wolff <t...@towo.net> Signed-off-by: Takashi Yano <takashi.y...@nifty.ne.jp> Diff: --- winsup/cygwin/fhandler/pty.cc | 6 +----- winsup/cygwin/local_includes/fhandler.h | 1 - winsup/cygwin/local_includes/tty.h | 1 - winsup/cygwin/select.cc | 16 +++++++++++----- winsup/cygwin/tty.cc | 1 - 5 files changed, 12 insertions(+), 13 deletions(-) diff --git a/winsup/cygwin/fhandler/pty.cc b/winsup/cygwin/fhandler/pty.cc index 77a363eb0..679068ea2 100644 --- a/winsup/cygwin/fhandler/pty.cc +++ b/winsup/cygwin/fhandler/pty.cc @@ -693,8 +693,7 @@ fhandler_pty_master::process_slave_output (char *buf, size_t len, int pktmode_on termios_printf ("bytes read %u", n); - if (!buf || ((get_ttyp ()->ti.c_lflag & FLUSHO) - && !get_ttyp ()->mask_flusho)) + if (!buf || (get_ttyp ()->ti.c_lflag & FLUSHO)) continue; /* Discard read data */ memcpy (optr, outbuf, n); @@ -714,8 +713,6 @@ fhandler_pty_master::process_slave_output (char *buf, size_t len, int pktmode_on } out: - if (buf) - set_mask_flusho (false); termios_printf ("returning %d", rc); return rc; } @@ -2256,7 +2253,6 @@ fhandler_pty_master::write (const void *ptr, size_t len) nlen--; i--; } - process_stop_start (buf[i], get_ttyp ()); } DWORD n; diff --git a/winsup/cygwin/local_includes/fhandler.h b/winsup/cygwin/local_includes/fhandler.h index 4db2964fe..bdd87ebb7 100644 --- a/winsup/cygwin/local_includes/fhandler.h +++ b/winsup/cygwin/local_includes/fhandler.h @@ -2625,7 +2625,6 @@ public: } void get_master_thread_param (master_thread_param_t *p); void get_master_fwd_thread_param (master_fwd_thread_param_t *p); - void set_mask_flusho (bool m) { get_ttyp ()->mask_flusho = m; } bool need_send_ctrl_c_event (); }; diff --git a/winsup/cygwin/local_includes/tty.h b/winsup/cygwin/local_includes/tty.h index a418ab1f9..9485e24c5 100644 --- a/winsup/cygwin/local_includes/tty.h +++ b/winsup/cygwin/local_includes/tty.h @@ -139,7 +139,6 @@ private: bool master_is_running_as_service; bool req_xfer_input; xfer_dir pty_input_state; - bool mask_flusho; bool discard_input; bool stop_fwd_thread; diff --git a/winsup/cygwin/select.cc b/winsup/cygwin/select.cc index a7e82a024..8a94ac076 100644 --- a/winsup/cygwin/select.cc +++ b/winsup/cygwin/select.cc @@ -689,6 +689,8 @@ pipe_data_available (int fd, fhandler_base *fh, HANDLE h, int mode) return 0; } +SRWLOCK ptym_peek_lock = SRWLOCK_INIT; + static int peek_pipe (select_record *s, bool from_select) { @@ -730,10 +732,19 @@ peek_pipe (select_record *s, bool from_select) gotone = s->read_ready = true; goto out; } + if (fh->get_major () == DEV_PTYM_MAJOR) + AcquireSRWLockExclusive (&ptym_peek_lock); ssize_t n = pipe_data_available (s->fd, fh, h, PDA_READ); /* On PTY masters, check if input from the echo pipe is available. */ if (n == 0 && fh->get_echo_handle ()) n = pipe_data_available (s->fd, fh, fh->get_echo_handle (), PDA_READ); + if (fh->get_major () == DEV_PTYM_MAJOR) + { + fhandler_pty_master *fhm = (fhandler_pty_master *) fh; + while (n > 0 && (fhm->tc ()->ti.c_lflag & FLUSHO)) + n = fhm->process_slave_output (NULL, n, 0); /* Discard pipe data */ + ReleaseSRWLockExclusive (&ptym_peek_lock); + } if (n == PDA_ERROR) { @@ -759,11 +770,6 @@ peek_pipe (select_record *s, bool from_select) } out: - if (fh->get_major () == DEV_PTYM_MAJOR) - { - fhandler_pty_master *fhm = (fhandler_pty_master *) fh; - fhm->set_mask_flusho (s->read_ready); - } h = fh->get_output_handle (); if (s->write_selected && dev != FH_PIPER) { diff --git a/winsup/cygwin/tty.cc b/winsup/cygwin/tty.cc index a4b716721..0c49dc2bd 100644 --- a/winsup/cygwin/tty.cc +++ b/winsup/cygwin/tty.cc @@ -253,7 +253,6 @@ tty::init () req_xfer_input = false; pty_input_state = to_cyg; last_sig = 0; - mask_flusho = false; discard_input = false; stop_fwd_thread = false; }