diff options
author | Takashi Yano <takashi.yano@nifty.ne.jp> | 2025-08-30 11:39:39 +0900 |
---|---|---|
committer | Takashi Yano <takashi.yano@nifty.ne.jp> | 2025-08-30 12:00:47 +0900 |
commit | 7b5fb35e376cfab42335291008758a2a64ff66b1 (patch) | |
tree | 59f4829ba7f8c9a216d67f2bd7a61c9ce3d8dae9 | |
parent | bd409f3c12e28e1464dec7fd0d45db30280f1e56 (diff) | |
download | newlib-7b5fb35e376cfab42335291008758a2a64ff66b1.zip newlib-7b5fb35e376cfab42335291008758a2a64ff66b1.tar.gz newlib-7b5fb35e376cfab42335291008758a2a64ff66b1.tar.bz2 |
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 <towo@towo.net>
Signed-off-by: Takashi Yano <takashi.yano@nifty.ne.jp>
-rw-r--r-- | winsup/cygwin/fhandler/pty.cc | 6 | ||||
-rw-r--r-- | winsup/cygwin/local_includes/fhandler.h | 1 | ||||
-rw-r--r-- | winsup/cygwin/local_includes/tty.h | 1 | ||||
-rw-r--r-- | winsup/cygwin/select.cc | 16 | ||||
-rw-r--r-- | 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 77a363e..679068e 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 4db2964..bdd87eb 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 a418ab1..9485e24 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 a7e82a0..8a94ac0 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 a4b7167..0c49dc2 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; } |