Cygwin: pty: Discard input already accepted on interrupt.

- Currently, input already accepted is not discarded on interrupt
  by VINTR, VQUIT and VSUSP keys. This patch fixes the issue.
This commit is contained in:
Takashi Yano via Cygwin-patches 2021-03-05 18:01:50 +09:00 committed by Corinna Vinschen
parent 582628d551
commit 4e16e575db
5 changed files with 31 additions and 1 deletions

View File

@ -1921,6 +1921,7 @@ class fhandler_termios: public fhandler_base
int eat_readahead (int n); int eat_readahead (int n);
virtual void acquire_input_mutex_if_necessary (DWORD ms) {}; virtual void acquire_input_mutex_if_necessary (DWORD ms) {};
virtual void release_input_mutex_if_necessary (void) {}; virtual void release_input_mutex_if_necessary (void) {};
virtual void discard_input () {};
public: public:
tty_min*& tc () {return _tc;} tty_min*& tc () {return _tc;}
@ -2451,6 +2452,7 @@ public:
void fixup_after_exec (); void fixup_after_exec ();
int tcgetpgrp (); int tcgetpgrp ();
void flush_to_slave (); void flush_to_slave ();
void discard_input ();
fhandler_pty_master (void *) {} fhandler_pty_master (void *) {}

View File

@ -333,7 +333,10 @@ fhandler_termios::line_edit (const char *rptr, size_t nread, termios& ti,
termios_printf ("got interrupt %d, sending signal %d", c, sig); termios_printf ("got interrupt %d, sending signal %d", c, sig);
if (!(ti.c_lflag & NOFLSH)) if (!(ti.c_lflag & NOFLSH))
eat_readahead (-1); {
eat_readahead (-1);
discard_input ();
}
release_input_mutex_if_necessary (); release_input_mutex_if_necessary ();
tc ()->kill_pgrp (sig); tc ()->kill_pgrp (sig);
acquire_input_mutex_if_necessary (INFINITE); acquire_input_mutex_if_necessary (INFINITE);

View File

@ -391,6 +391,21 @@ fhandler_pty_master::flush_to_slave ()
accept_input (); accept_input ();
} }
void
fhandler_pty_master::discard_input ()
{
DWORD bytes_in_pipe;
char buf[1024];
DWORD n;
WaitForSingleObject (input_mutex, INFINITE);
while (::bytes_available (bytes_in_pipe, from_master_cyg) && bytes_in_pipe)
ReadFile (from_master_cyg, buf, sizeof(buf), &n, NULL);
ResetEvent (input_available_event);
get_ttyp ()->discard_input = true;
ReleaseMutex (input_mutex);
}
DWORD DWORD
fhandler_pty_common::__acquire_output_mutex (const char *fn, int ln, fhandler_pty_common::__acquire_output_mutex (const char *fn, int ln,
DWORD ms) DWORD ms)
@ -2150,6 +2165,9 @@ fhandler_pty_master::write (const void *ptr, size_t len)
} }
WaitForSingleObject (input_mutex, INFINITE); WaitForSingleObject (input_mutex, INFINITE);
if ((ti.c_lflag & ISIG) && !(ti.c_iflag & IGNBRK)
&& !(ti.c_lflag & NOFLSH) && memchr (buf, '\003', nlen))
get_ttyp ()->discard_input = true;
DWORD n; DWORD n;
WriteFile (to_slave, buf, nlen, &n, NULL); WriteFile (to_slave, buf, nlen, &n, NULL);
ReleaseMutex (input_mutex); ReleaseMutex (input_mutex);
@ -3709,6 +3727,8 @@ fhandler_pty_slave::transfer_input (tty::xfer_dir dir, HANDLE from, tty *ttyp,
while (PeekConsoleInputA (from, r, INREC_SIZE, &n) && n) while (PeekConsoleInputA (from, r, INREC_SIZE, &n) && n)
{ {
ReadConsoleInputA (from, r, n, &n); ReadConsoleInputA (from, r, n, &n);
if (ttyp->discard_input)
continue;
int len = 0; int len = 0;
char *ptr = buf; char *ptr = buf;
for (DWORD i = 0; i < n; i++) for (DWORD i = 0; i < n; i++)
@ -3773,6 +3793,8 @@ fhandler_pty_slave::transfer_input (tty::xfer_dir dir, HANDLE from, tty *ttyp,
{ {
DWORD n = MIN (bytes_in_pipe, NT_MAX_PATH); DWORD n = MIN (bytes_in_pipe, NT_MAX_PATH);
ReadFile (from, buf, n, &n, NULL); ReadFile (from, buf, n, &n, NULL);
if (ttyp->discard_input)
continue;
char *ptr = buf; char *ptr = buf;
if (dir == tty::to_nat) if (dir == tty::to_nat)
{ {
@ -3803,4 +3825,5 @@ fhandler_pty_slave::transfer_input (tty::xfer_dir dir, HANDLE from, tty *ttyp,
else if (transfered) else if (transfered)
SetEvent (input_available_event); SetEvent (input_available_event);
ttyp->pcon_input_state = dir; ttyp->pcon_input_state = dir;
ttyp->discard_input = false;
} }

View File

@ -253,6 +253,7 @@ tty::init ()
pcon_input_state = to_cyg; pcon_input_state = to_cyg;
last_sig = 0; last_sig = 0;
mask_flusho = false; mask_flusho = false;
discard_input = false;
} }
HANDLE HANDLE

View File

@ -131,6 +131,7 @@ private:
bool req_xfer_input; bool req_xfer_input;
xfer_dir pcon_input_state; xfer_dir pcon_input_state;
bool mask_flusho; bool mask_flusho;
bool discard_input;
public: public:
HANDLE from_master () const { return _from_master; } HANDLE from_master () const { return _from_master; }