Cygwin: console: Change timing of set/unset xterm compatible mode.
- If two cygwin programs are executed simultaneousley with pipes in cmd.exe, xterm compatible mode is accidentally disabled by the process which ends first. After that, escape sequences are not handled correctly in the other app. This is the problem 2 reported in https://cygwin.com/ml/cygwin/2020-02/msg00116.html. This patch fixes the issue. This patch also fixes the problem 3. For these issues, the timing of setting and unsetting xterm compatible mode is changed. For read, xterm compatible mode is enabled only within read() or select() functions. For write, it is enabled every time write() is called, and restored on close().
This commit is contained in:
parent
bb25dd1b0f
commit
774b8996d1
@ -53,7 +53,6 @@ fhandler_console::console_state NO_COPY *fhandler_console::shared_console_info;
|
|||||||
|
|
||||||
bool NO_COPY fhandler_console::invisible_console;
|
bool NO_COPY fhandler_console::invisible_console;
|
||||||
|
|
||||||
static DWORD orig_conin_mode = (DWORD) -1;
|
|
||||||
static DWORD orig_conout_mode = (DWORD) -1;
|
static DWORD orig_conout_mode = (DWORD) -1;
|
||||||
|
|
||||||
/* con_ra is shared in the same process.
|
/* con_ra is shared in the same process.
|
||||||
@ -361,6 +360,9 @@ fix_tab_position (HANDLE h, SHORT width)
|
|||||||
__small_sprintf (buf+strlen (buf), "\033[%d;%dH\033H", 1, col+1);
|
__small_sprintf (buf+strlen (buf), "\033[%d;%dH\033H", 1, col+1);
|
||||||
/* Restore cursor position */
|
/* Restore cursor position */
|
||||||
__small_sprintf (buf+strlen (buf), "\0338");
|
__small_sprintf (buf+strlen (buf), "\0338");
|
||||||
|
DWORD dwMode;
|
||||||
|
GetConsoleMode (h, &dwMode);
|
||||||
|
SetConsoleMode (h, dwMode | ENABLE_VIRTUAL_TERMINAL_PROCESSING);
|
||||||
DWORD dwLen;
|
DWORD dwLen;
|
||||||
WriteConsole (h, buf, strlen (buf), &dwLen, 0);
|
WriteConsole (h, buf, strlen (buf), &dwLen, 0);
|
||||||
}
|
}
|
||||||
@ -425,12 +427,19 @@ fhandler_console::read (void *pv, size_t& buflen)
|
|||||||
|
|
||||||
set_input_state ();
|
set_input_state ();
|
||||||
|
|
||||||
|
DWORD dwMode;
|
||||||
|
GetConsoleMode (get_handle (), &dwMode);
|
||||||
|
/* if system has 24 bit color capability, use xterm compatible mode. */
|
||||||
|
if (wincap.has_con_24bit_colors () && !con_is_legacy)
|
||||||
|
SetConsoleMode (get_handle (), dwMode | ENABLE_VIRTUAL_TERMINAL_INPUT);
|
||||||
|
|
||||||
while (!input_ready && !get_cons_readahead_valid ())
|
while (!input_ready && !get_cons_readahead_valid ())
|
||||||
{
|
{
|
||||||
int bgres;
|
int bgres;
|
||||||
if ((bgres = bg_check (SIGTTIN)) <= bg_eof)
|
if ((bgres = bg_check (SIGTTIN)) <= bg_eof)
|
||||||
{
|
{
|
||||||
buflen = bgres;
|
buflen = bgres;
|
||||||
|
SetConsoleMode (get_handle (), dwMode); /* Restore */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -448,6 +457,7 @@ fhandler_console::read (void *pv, size_t& buflen)
|
|||||||
case WAIT_TIMEOUT:
|
case WAIT_TIMEOUT:
|
||||||
set_sig_errno (EAGAIN);
|
set_sig_errno (EAGAIN);
|
||||||
buflen = (size_t) -1;
|
buflen = (size_t) -1;
|
||||||
|
SetConsoleMode (get_handle (), dwMode); /* Restore */
|
||||||
return;
|
return;
|
||||||
default:
|
default:
|
||||||
goto err;
|
goto err;
|
||||||
@ -495,30 +505,24 @@ fhandler_console::read (void *pv, size_t& buflen)
|
|||||||
#undef buf
|
#undef buf
|
||||||
|
|
||||||
buflen = copied_chars;
|
buflen = copied_chars;
|
||||||
|
SetConsoleMode (get_handle (), dwMode); /* Restore */
|
||||||
return;
|
return;
|
||||||
|
|
||||||
err:
|
err:
|
||||||
__seterrno ();
|
__seterrno ();
|
||||||
buflen = (size_t) -1;
|
buflen = (size_t) -1;
|
||||||
|
SetConsoleMode (get_handle (), dwMode); /* Restore */
|
||||||
return;
|
return;
|
||||||
|
|
||||||
sig_exit:
|
sig_exit:
|
||||||
set_sig_errno (EINTR);
|
set_sig_errno (EINTR);
|
||||||
buflen = (size_t) -1;
|
buflen = (size_t) -1;
|
||||||
|
SetConsoleMode (get_handle (), dwMode); /* Restore */
|
||||||
}
|
}
|
||||||
|
|
||||||
fhandler_console::input_states
|
fhandler_console::input_states
|
||||||
fhandler_console::process_input_message (void)
|
fhandler_console::process_input_message (void)
|
||||||
{
|
{
|
||||||
if (wincap.has_con_24bit_colors () && !con_is_legacy)
|
|
||||||
{
|
|
||||||
DWORD dwMode;
|
|
||||||
/* Enable xterm compatible mode in input */
|
|
||||||
GetConsoleMode (get_handle (), &dwMode);
|
|
||||||
dwMode |= ENABLE_VIRTUAL_TERMINAL_INPUT;
|
|
||||||
SetConsoleMode (get_handle (), dwMode);
|
|
||||||
}
|
|
||||||
|
|
||||||
char tmp[60];
|
char tmp[60];
|
||||||
|
|
||||||
if (!shared_console_info)
|
if (!shared_console_info)
|
||||||
@ -1047,29 +1051,26 @@ fhandler_console::open (int flags, mode_t)
|
|||||||
get_ttyp ()->rstcons (false);
|
get_ttyp ()->rstcons (false);
|
||||||
set_open_status ();
|
set_open_status ();
|
||||||
|
|
||||||
if (orig_conin_mode == (DWORD) -1)
|
|
||||||
GetConsoleMode (get_handle (), &orig_conin_mode);
|
|
||||||
if (orig_conout_mode == (DWORD) -1)
|
if (orig_conout_mode == (DWORD) -1)
|
||||||
GetConsoleMode (get_output_handle (), &orig_conout_mode);
|
GetConsoleMode (get_output_handle (), &orig_conout_mode);
|
||||||
|
|
||||||
if (getpid () == con.owner && wincap.has_con_24bit_colors ())
|
if (getpid () == con.owner && wincap.has_con_24bit_colors ())
|
||||||
{
|
{
|
||||||
|
bool is_legacy = false;
|
||||||
DWORD dwMode;
|
DWORD dwMode;
|
||||||
/* Enable xterm compatible mode in output */
|
/* Check xterm compatible mode in output */
|
||||||
GetConsoleMode (get_output_handle (), &dwMode);
|
GetConsoleMode (get_output_handle (), &dwMode);
|
||||||
dwMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
|
if (!SetConsoleMode (get_output_handle (),
|
||||||
if (!SetConsoleMode (get_output_handle (), dwMode))
|
dwMode | ENABLE_VIRTUAL_TERMINAL_PROCESSING))
|
||||||
con.is_legacy = true;
|
is_legacy = true;
|
||||||
else
|
SetConsoleMode (get_output_handle (), dwMode);
|
||||||
con.is_legacy = false;
|
/* Check xterm compatible mode in input */
|
||||||
/* Enable xterm compatible mode in input */
|
GetConsoleMode (get_handle (), &dwMode);
|
||||||
if (!con_is_legacy)
|
if (!SetConsoleMode (get_handle (),
|
||||||
{
|
dwMode | ENABLE_VIRTUAL_TERMINAL_INPUT))
|
||||||
GetConsoleMode (get_handle (), &dwMode);
|
is_legacy = true;
|
||||||
dwMode |= ENABLE_VIRTUAL_TERMINAL_INPUT;
|
SetConsoleMode (get_handle (), dwMode);
|
||||||
if (!SetConsoleMode (get_handle (), dwMode))
|
con.is_legacy = is_legacy;
|
||||||
con.is_legacy = true;
|
|
||||||
}
|
|
||||||
extern int sawTERM;
|
extern int sawTERM;
|
||||||
if (con_is_legacy && !sawTERM)
|
if (con_is_legacy && !sawTERM)
|
||||||
setenv ("TERM", "cygwin", 1);
|
setenv ("TERM", "cygwin", 1);
|
||||||
@ -1102,19 +1103,12 @@ fhandler_console::close ()
|
|||||||
{
|
{
|
||||||
debug_printf ("closing: %p, %p", get_handle (), get_output_handle ());
|
debug_printf ("closing: %p, %p", get_handle (), get_output_handle ());
|
||||||
|
|
||||||
CloseHandle (input_mutex);
|
acquire_output_mutex (INFINITE);
|
||||||
input_mutex = NULL;
|
|
||||||
CloseHandle (output_mutex);
|
|
||||||
output_mutex = NULL;
|
|
||||||
|
|
||||||
if (shared_console_info && getpid () == con.owner &&
|
if (shared_console_info && getpid () == con.owner &&
|
||||||
wincap.has_con_24bit_colors () && !con_is_legacy)
|
wincap.has_con_24bit_colors () && !con_is_legacy)
|
||||||
{
|
{
|
||||||
DWORD dwMode;
|
DWORD dwMode;
|
||||||
/* Disable xterm compatible mode in input */
|
|
||||||
GetConsoleMode (get_handle (), &dwMode);
|
|
||||||
dwMode &= ~ENABLE_VIRTUAL_TERMINAL_INPUT;
|
|
||||||
SetConsoleMode (get_handle (), dwMode);
|
|
||||||
/* Disable xterm compatible mode in output */
|
/* Disable xterm compatible mode in output */
|
||||||
GetConsoleMode (get_output_handle (), &dwMode);
|
GetConsoleMode (get_output_handle (), &dwMode);
|
||||||
dwMode &= ~ENABLE_VIRTUAL_TERMINAL_PROCESSING;
|
dwMode &= ~ENABLE_VIRTUAL_TERMINAL_PROCESSING;
|
||||||
@ -1127,12 +1121,15 @@ fhandler_console::close ()
|
|||||||
status = NtQueryObject (get_handle (), ObjectBasicInformation,
|
status = NtQueryObject (get_handle (), ObjectBasicInformation,
|
||||||
&obi, sizeof obi, NULL);
|
&obi, sizeof obi, NULL);
|
||||||
if (NT_SUCCESS (status) && obi.HandleCount == 1)
|
if (NT_SUCCESS (status) && obi.HandleCount == 1)
|
||||||
{
|
if (orig_conout_mode != (DWORD) -1)
|
||||||
if (orig_conin_mode != (DWORD) -1)
|
SetConsoleMode (get_handle (), orig_conout_mode);
|
||||||
SetConsoleMode (get_handle (), orig_conin_mode);
|
|
||||||
if (orig_conout_mode != (DWORD) -1)
|
release_output_mutex ();
|
||||||
SetConsoleMode (get_handle (), orig_conout_mode);
|
|
||||||
}
|
CloseHandle (input_mutex);
|
||||||
|
input_mutex = NULL;
|
||||||
|
CloseHandle (output_mutex);
|
||||||
|
output_mutex = NULL;
|
||||||
|
|
||||||
CloseHandle (get_handle ());
|
CloseHandle (get_handle ());
|
||||||
CloseHandle (get_output_handle ());
|
CloseHandle (get_output_handle ());
|
||||||
@ -1270,13 +1267,6 @@ fhandler_console::output_tcsetattr (int, struct termios const *t)
|
|||||||
|
|
||||||
acquire_output_mutex (INFINITE);
|
acquire_output_mutex (INFINITE);
|
||||||
DWORD flags = ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT;
|
DWORD flags = ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT;
|
||||||
/* If system has 24 bit color capability, use xterm compatible mode. */
|
|
||||||
if (wincap.has_con_24bit_colors () && !con_is_legacy)
|
|
||||||
{
|
|
||||||
flags |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
|
|
||||||
if (!(t->c_oflag & OPOST) || !(t->c_oflag & ONLCR))
|
|
||||||
flags |= DISABLE_NEWLINE_AUTO_RETURN;
|
|
||||||
}
|
|
||||||
|
|
||||||
int res = SetConsoleMode (get_output_handle (), flags) ? 0 : -1;
|
int res = SetConsoleMode (get_output_handle (), flags) ? 0 : -1;
|
||||||
if (res)
|
if (res)
|
||||||
@ -1338,9 +1328,6 @@ fhandler_console::input_tcsetattr (int, struct termios const *t)
|
|||||||
flags |= ENABLE_WINDOW_INPUT |
|
flags |= ENABLE_WINDOW_INPUT |
|
||||||
((wincap.has_con_24bit_colors () && !con_is_legacy) ?
|
((wincap.has_con_24bit_colors () && !con_is_legacy) ?
|
||||||
0 : ENABLE_MOUSE_INPUT);
|
0 : ENABLE_MOUSE_INPUT);
|
||||||
/* if system has 24 bit color capability, use xterm compatible mode. */
|
|
||||||
if (wincap.has_con_24bit_colors () && !con_is_legacy)
|
|
||||||
flags |= ENABLE_VIRTUAL_TERMINAL_INPUT;
|
|
||||||
|
|
||||||
int res;
|
int res;
|
||||||
if (flags == oflags)
|
if (flags == oflags)
|
||||||
@ -2716,6 +2703,20 @@ fhandler_console::write (const void *vsrc, size_t len)
|
|||||||
push_process_state process_state (PID_TTYOU);
|
push_process_state process_state (PID_TTYOU);
|
||||||
acquire_output_mutex (INFINITE);
|
acquire_output_mutex (INFINITE);
|
||||||
|
|
||||||
|
/* If system has 24 bit color capability, use xterm compatible mode. */
|
||||||
|
if (wincap.has_con_24bit_colors () && !con_is_legacy)
|
||||||
|
{
|
||||||
|
DWORD dwMode;
|
||||||
|
GetConsoleMode (get_output_handle (), &dwMode);
|
||||||
|
dwMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
|
||||||
|
if (!(get_ttyp ()->ti.c_oflag & OPOST) ||
|
||||||
|
!(get_ttyp ()->ti.c_oflag & ONLCR))
|
||||||
|
dwMode |= DISABLE_NEWLINE_AUTO_RETURN;
|
||||||
|
else
|
||||||
|
dwMode &= ~DISABLE_NEWLINE_AUTO_RETURN;
|
||||||
|
SetConsoleMode (get_output_handle (), dwMode);
|
||||||
|
}
|
||||||
|
|
||||||
/* Run and check for ansi sequences */
|
/* Run and check for ansi sequences */
|
||||||
unsigned const char *src = (unsigned char *) vsrc;
|
unsigned const char *src = (unsigned char *) vsrc;
|
||||||
unsigned const char *end = src + len;
|
unsigned const char *end = src + len;
|
||||||
|
@ -1075,19 +1075,49 @@ verify_console (select_record *me, fd_set *rfds, fd_set *wfds,
|
|||||||
return peek_console (me, true);
|
return peek_console (me, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
console_startup (select_record *me, select_stuff *stuff)
|
||||||
|
{
|
||||||
|
select_record *s = stuff->start.next;
|
||||||
|
if (wincap.has_con_24bit_colors ())
|
||||||
|
{
|
||||||
|
DWORD dwMode;
|
||||||
|
GetConsoleMode (s->h, &dwMode);
|
||||||
|
/* Enable xterm compatible mode in input */
|
||||||
|
dwMode |= ENABLE_VIRTUAL_TERMINAL_INPUT;
|
||||||
|
SetConsoleMode (s->h, dwMode);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
console_cleanup (select_record *me, select_stuff *stuff)
|
||||||
|
{
|
||||||
|
select_record *s = stuff->start.next;
|
||||||
|
if (wincap.has_con_24bit_colors ())
|
||||||
|
{
|
||||||
|
DWORD dwMode;
|
||||||
|
GetConsoleMode (s->h, &dwMode);
|
||||||
|
/* Disable xterm compatible mode in input */
|
||||||
|
dwMode &= ~ENABLE_VIRTUAL_TERMINAL_INPUT;
|
||||||
|
SetConsoleMode (s->h, dwMode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
select_record *
|
select_record *
|
||||||
fhandler_console::select_read (select_stuff *ss)
|
fhandler_console::select_read (select_stuff *ss)
|
||||||
{
|
{
|
||||||
select_record *s = ss->start.next;
|
select_record *s = ss->start.next;
|
||||||
if (!s->startup)
|
if (!s->startup)
|
||||||
{
|
{
|
||||||
s->startup = no_startup;
|
s->startup = console_startup;
|
||||||
s->verify = verify_console;
|
s->verify = verify_console;
|
||||||
set_cursor_maybe ();
|
set_cursor_maybe ();
|
||||||
}
|
}
|
||||||
|
|
||||||
s->peek = peek_console;
|
s->peek = peek_console;
|
||||||
s->h = get_handle ();
|
s->h = get_handle ();
|
||||||
|
s->cleanup = console_cleanup;
|
||||||
s->read_selected = true;
|
s->read_selected = true;
|
||||||
s->read_ready = input_ready || get_cons_readahead_valid ();
|
s->read_ready = input_ready || get_cons_readahead_valid ();
|
||||||
return s;
|
return s;
|
||||||
|
@ -615,22 +615,13 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv,
|
|||||||
{
|
{
|
||||||
attach_to_console = true;
|
attach_to_console = true;
|
||||||
if (wincap.has_con_24bit_colors () && !iscygwin ())
|
if (wincap.has_con_24bit_colors () && !iscygwin ())
|
||||||
{
|
if (fd == 1 || fd == 2)
|
||||||
DWORD dwMode;
|
{
|
||||||
if (fd == 0)
|
DWORD dwMode;
|
||||||
{
|
GetConsoleMode (fh->get_output_handle (), &dwMode);
|
||||||
/* Disable xterm compatible mode in input */
|
dwMode &= ~ENABLE_VIRTUAL_TERMINAL_PROCESSING;
|
||||||
GetConsoleMode (fh->get_handle (), &dwMode);
|
SetConsoleMode (fh->get_output_handle (), dwMode);
|
||||||
dwMode &= ~ENABLE_VIRTUAL_TERMINAL_INPUT;
|
}
|
||||||
SetConsoleMode (fh->get_handle (), dwMode);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
GetConsoleMode (fh->get_output_handle (), &dwMode);
|
|
||||||
dwMode &= ~ENABLE_VIRTUAL_TERMINAL_PROCESSING;
|
|
||||||
SetConsoleMode (fh->get_output_handle (), dwMode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user