Cygwin: console: Fix issues of apps which open pty.
- After some recent changes for special keys handling break the apps which open pty (such as script command). If the app which opens pty is executed in console, the following issues occur. 1) If the script command was started from non-cygwin shell (such as cmd.exe), another cygwin app started in pty slave cannot receive Ctrl-C. 2) If non-cygwin app is executed in pty slave, the app which opened the pty (e.g. script command) crashes by Ctrl-C. This patch fixes these issues.
This commit is contained in:
parent
69d93f3121
commit
32401ad98e
|
@ -1921,7 +1921,7 @@ class fhandler_termios: public fhandler_base
|
||||||
HANDLE& get_output_handle_nat () { return output_handle; }
|
HANDLE& get_output_handle_nat () { return output_handle; }
|
||||||
static process_sig_state process_sigs (char c, tty *ttyp,
|
static process_sig_state process_sigs (char c, tty *ttyp,
|
||||||
fhandler_termios *fh);
|
fhandler_termios *fh);
|
||||||
static bool process_stop_start (char c, tty *ttyp, bool on_ixany);
|
static bool process_stop_start (char c, tty *ttyp);
|
||||||
line_edit_status line_edit (const char *rptr, size_t nread, termios&,
|
line_edit_status line_edit (const char *rptr, size_t nread, termios&,
|
||||||
ssize_t *bytes_read = NULL);
|
ssize_t *bytes_read = NULL);
|
||||||
void set_output_handle (HANDLE h) { output_handle = h; }
|
void set_output_handle (HANDLE h) { output_handle = h; }
|
||||||
|
|
|
@ -189,7 +189,7 @@ void
|
||||||
fhandler_console::cons_master_thread (handle_set_t *p, tty *ttyp)
|
fhandler_console::cons_master_thread (handle_set_t *p, tty *ttyp)
|
||||||
{
|
{
|
||||||
termios &ti = ttyp->ti;
|
termios &ti = ttyp->ti;
|
||||||
DWORD output_stopped_at = 0;
|
int processed_up_to = -1;
|
||||||
while (con.owner == myself->pid)
|
while (con.owner == myself->pid)
|
||||||
{
|
{
|
||||||
DWORD total_read, n, i;
|
DWORD total_read, n, i;
|
||||||
|
@ -210,6 +210,7 @@ fhandler_console::cons_master_thread (handle_set_t *p, tty *ttyp)
|
||||||
input_rec, INREC_SIZE, &total_read);
|
input_rec, INREC_SIZE, &total_read);
|
||||||
break;
|
break;
|
||||||
case WAIT_TIMEOUT:
|
case WAIT_TIMEOUT:
|
||||||
|
processed_up_to = -1;
|
||||||
case WAIT_SIGNALED:
|
case WAIT_SIGNALED:
|
||||||
case WAIT_CANCELED:
|
case WAIT_CANCELED:
|
||||||
break;
|
break;
|
||||||
|
@ -232,11 +233,10 @@ fhandler_console::cons_master_thread (handle_set_t *p, tty *ttyp)
|
||||||
ttyp->kill_pgrp (SIGWINCH);
|
ttyp->kill_pgrp (SIGWINCH);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (i = 0; i < total_read; i++)
|
for (i = processed_up_to + 1; i < total_read; i++)
|
||||||
{
|
{
|
||||||
wchar_t wc;
|
wchar_t wc;
|
||||||
char c;
|
char c;
|
||||||
bool was_output_stopped;
|
|
||||||
bool processed = false;
|
bool processed = false;
|
||||||
switch (input_rec[i].EventType)
|
switch (input_rec[i].EventType)
|
||||||
{
|
{
|
||||||
|
@ -256,14 +256,12 @@ fhandler_console::cons_master_thread (handle_set_t *p, tty *ttyp)
|
||||||
ttyp->output_stopped = false;
|
ttyp->output_stopped = false;
|
||||||
if (ti.c_lflag & NOFLSH)
|
if (ti.c_lflag & NOFLSH)
|
||||||
goto remove_record;
|
goto remove_record;
|
||||||
|
processed_up_to = -1;
|
||||||
goto skip_writeback;
|
goto skip_writeback;
|
||||||
default: /* not signalled */
|
default: /* not signalled */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
was_output_stopped = ttyp->output_stopped;
|
processed = process_stop_start (c, ttyp);
|
||||||
processed = process_stop_start (c, ttyp, i > output_stopped_at);
|
|
||||||
if (!was_output_stopped && ttyp->output_stopped)
|
|
||||||
output_stopped_at = i;
|
|
||||||
break;
|
break;
|
||||||
case WINDOW_BUFFER_SIZE_EVENT:
|
case WINDOW_BUFFER_SIZE_EVENT:
|
||||||
SHORT y = con.dwWinSize.Y;
|
SHORT y = con.dwWinSize.Y;
|
||||||
|
@ -284,14 +282,16 @@ fhandler_console::cons_master_thread (handle_set_t *p, tty *ttyp)
|
||||||
remove_record:
|
remove_record:
|
||||||
if (processed)
|
if (processed)
|
||||||
{ /* Remove corresponding record. */
|
{ /* Remove corresponding record. */
|
||||||
memmove (input_rec + i, input_rec + i + 1,
|
if (total_read > i + 1)
|
||||||
sizeof (INPUT_RECORD) * (total_read - i - 1));
|
memmove (input_rec + i, input_rec + i + 1,
|
||||||
|
sizeof (INPUT_RECORD) * (total_read - i - 1));
|
||||||
total_read--;
|
total_read--;
|
||||||
i--;
|
i--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
processed_up_to = total_read - 1;
|
||||||
if (total_read)
|
if (total_read)
|
||||||
/* Write back input records other than interrupt. */
|
/* Writeback input records other than interrupt. */
|
||||||
WriteConsoleInputW (p->input_handle, input_rec, total_read, &n);
|
WriteConsoleInputW (p->input_handle, input_rec, total_read, &n);
|
||||||
skip_writeback:
|
skip_writeback:
|
||||||
ReleaseMutex (p->input_mutex);
|
ReleaseMutex (p->input_mutex);
|
||||||
|
|
|
@ -344,10 +344,12 @@ fhandler_termios::process_sigs (char c, tty* ttyp, fhandler_termios *fh)
|
||||||
(myself->dwProcessId, false);
|
(myself->dwProcessId, false);
|
||||||
if (resume_pid && fh && !fh->is_console ())
|
if (resume_pid && fh && !fh->is_console ())
|
||||||
{
|
{
|
||||||
|
if (::cygheap->ctty && ::cygheap->ctty->is_console ())
|
||||||
|
init_console_handler (false);
|
||||||
FreeConsole ();
|
FreeConsole ();
|
||||||
AttachConsole (p->dwProcessId);
|
AttachConsole (p->dwProcessId);
|
||||||
}
|
}
|
||||||
if (fh && p == myself)
|
if (fh && p == myself && being_debugged ())
|
||||||
{ /* Avoid deadlock in gdb on console. */
|
{ /* Avoid deadlock in gdb on console. */
|
||||||
fh->tcflush(TCIFLUSH);
|
fh->tcflush(TCIFLUSH);
|
||||||
fh->release_input_mutex_if_necessary ();
|
fh->release_input_mutex_if_necessary ();
|
||||||
|
@ -372,6 +374,8 @@ fhandler_termios::process_sigs (char c, tty* ttyp, fhandler_termios *fh)
|
||||||
{
|
{
|
||||||
FreeConsole ();
|
FreeConsole ();
|
||||||
AttachConsole (resume_pid);
|
AttachConsole (resume_pid);
|
||||||
|
if (::cygheap->ctty && ::cygheap->ctty->is_console ())
|
||||||
|
init_console_handler (true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (p && p->ctty == ttyp->ntty && p->pgid == pgid)
|
if (p && p->ctty == ttyp->ntty && p->pgid == pgid)
|
||||||
|
@ -447,7 +451,7 @@ fhandler_termios::process_sigs (char c, tty* ttyp, fhandler_termios *fh)
|
||||||
return signalled;
|
return signalled;
|
||||||
}
|
}
|
||||||
not_a_sig:
|
not_a_sig:
|
||||||
if (need_discard_input)
|
if ((ti.c_lflag & ISIG) && need_discard_input)
|
||||||
{
|
{
|
||||||
if (!(ti.c_lflag & NOFLSH) && fh)
|
if (!(ti.c_lflag & NOFLSH) && fh)
|
||||||
{
|
{
|
||||||
|
@ -462,7 +466,7 @@ not_a_sig:
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
fhandler_termios::process_stop_start (char c, tty *ttyp, bool on_ixany)
|
fhandler_termios::process_stop_start (char c, tty *ttyp)
|
||||||
{
|
{
|
||||||
termios &ti = ttyp->ti;
|
termios &ti = ttyp->ti;
|
||||||
if (ti.c_iflag & IXON)
|
if (ti.c_iflag & IXON)
|
||||||
|
@ -478,7 +482,7 @@ restart_output:
|
||||||
ttyp->output_stopped = false;
|
ttyp->output_stopped = false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if ((ti.c_iflag & IXANY) && ttyp->output_stopped && on_ixany)
|
else if ((ti.c_iflag & IXANY) && ttyp->output_stopped)
|
||||||
goto restart_output;
|
goto restart_output;
|
||||||
}
|
}
|
||||||
if ((ti.c_lflag & ICANON) && (ti.c_lflag & IEXTEN)
|
if ((ti.c_lflag & ICANON) && (ti.c_lflag & IEXTEN)
|
||||||
|
@ -526,7 +530,7 @@ fhandler_termios::line_edit (const char *rptr, size_t nread, termios& ti,
|
||||||
default: /* Not signalled */
|
default: /* Not signalled */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (process_stop_start (c, get_ttyp (), true))
|
if (process_stop_start (c, get_ttyp ()))
|
||||||
continue;
|
continue;
|
||||||
/* Check for special chars */
|
/* Check for special chars */
|
||||||
if (c == '\r')
|
if (c == '\r')
|
||||||
|
|
|
@ -2301,7 +2301,7 @@ fhandler_pty_master::write (const void *ptr, size_t len)
|
||||||
nlen--;
|
nlen--;
|
||||||
i--;
|
i--;
|
||||||
}
|
}
|
||||||
process_stop_start (buf[i], get_ttyp (), true);
|
process_stop_start (buf[i], get_ttyp ());
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD n;
|
DWORD n;
|
||||||
|
|
Loading…
Reference in New Issue