aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTakashi Yano <takashi.yano@nifty.ne.jp>2025-08-30 11:39:39 +0900
committerTakashi Yano <takashi.yano@nifty.ne.jp>2025-08-30 12:00:47 +0900
commit7b5fb35e376cfab42335291008758a2a64ff66b1 (patch)
tree59f4829ba7f8c9a216d67f2bd7a61c9ce3d8dae9
parentbd409f3c12e28e1464dec7fd0d45db30280f1e56 (diff)
downloadnewlib-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.cc6
-rw-r--r--winsup/cygwin/local_includes/fhandler.h1
-rw-r--r--winsup/cygwin/local_includes/tty.h1
-rw-r--r--winsup/cygwin/select.cc16
-rw-r--r--winsup/cygwin/tty.cc1
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;
}