aboutsummaryrefslogtreecommitdiff
path: root/winsup/cygwin/fhandler/console.cc
diff options
context:
space:
mode:
Diffstat (limited to 'winsup/cygwin/fhandler/console.cc')
-rw-r--r--winsup/cygwin/fhandler/console.cc141
1 files changed, 108 insertions, 33 deletions
diff --git a/winsup/cygwin/fhandler/console.cc b/winsup/cygwin/fhandler/console.cc
index f162698..887e2ef 100644
--- a/winsup/cygwin/fhandler/console.cc
+++ b/winsup/cygwin/fhandler/console.cc
@@ -509,7 +509,7 @@ fhandler_console::cons_master_thread (handle_set_t *p, tty *ttyp)
case not_signalled_but_done:
case done_with_debugger:
processed = true;
- ttyp->output_stopped = false;
+ ttyp->output_stopped &= ~BY_VSTOP;
if (ti.c_lflag & NOFLSH)
goto remove_record;
con.num_processed = 0;
@@ -771,6 +771,8 @@ fhandler_console::setup ()
con.disable_master_thread = true;
con.master_thread_suspended = false;
con.num_processed = 0;
+ con.curr_input_mode = tty::restore;
+ con.curr_output_mode = tty::restore;
}
}
@@ -829,7 +831,7 @@ fhandler_console::set_input_mode (tty::cons_mode m, const termios *t,
break;
case tty::cygwin:
flags |= ENABLE_WINDOW_INPUT;
- if (con.master_thread_suspended)
+ if (con.master_thread_suspended || con.disable_master_thread)
flags |= ENABLE_PROCESSED_INPUT;
if (wincap.has_con_24bit_colors () && !con_is_legacy)
flags |= ENABLE_VIRTUAL_TERMINAL_INPUT;
@@ -849,11 +851,6 @@ fhandler_console::set_input_mode (tty::cons_mode m, const termios *t,
flags |= ENABLE_PROCESSED_INPUT;
break;
}
- if (con.curr_input_mode != tty::cygwin && m == tty::cygwin)
- {
- prev_input_mode_backup = con.prev_input_mode;
- con.prev_input_mode = oflags;
- }
con.curr_input_mode = m;
SetConsoleMode (p->input_handle, flags);
if (!(oflags & ENABLE_VIRTUAL_TERMINAL_INPUT)
@@ -893,11 +890,6 @@ fhandler_console::set_output_mode (tty::cons_mode m, const termios *t,
flags |= DISABLE_NEWLINE_AUTO_RETURN;
break;
}
- if (con.curr_output_mode != tty::cygwin && m == tty::cygwin)
- {
- prev_output_mode_backup = con.prev_output_mode;
- GetConsoleMode (p->output_handle, &con.prev_output_mode);
- }
con.curr_output_mode = m;
acquire_attach_mutex (mutex_timeout);
DWORD resume_pid = attach_console (con.owner);
@@ -913,13 +905,14 @@ fhandler_console::setup_for_non_cygwin_app ()
/* Setting-up console mode for non-cygwin app. */
/* If conmode is set to tty::native for non-cygwin apps
in background, tty settings of the shell is reflected
- to the console mode of the app. So, use tty::restore
- for background process instead. */
- tty::cons_mode conmode =
- (get_ttyp ()->getpgid ()== myself->pgid) ? tty::native : tty::restore;
- set_input_mode (conmode, &tc ()->ti, get_handle_set ());
- set_output_mode (conmode, &tc ()->ti, get_handle_set ());
- set_disable_master_thread (true, this);
+ to the console mode of the app. So, do not change the
+ console mode. */
+ if (get_ttyp ()->getpgid () == myself->pgid)
+ {
+ set_input_mode (tty::native, &tc ()->ti, get_handle_set ());
+ set_output_mode (tty::native, &tc ()->ti, get_handle_set ());
+ set_disable_master_thread (true, this);
+ }
}
void
@@ -930,12 +923,14 @@ fhandler_console::cleanup_for_non_cygwin_app (handle_set_t *p)
termios *ti = shared_console_info[unit] ?
&(shared_console_info[unit]->tty_min_state.ti) : &dummy;
/* Cleaning-up console mode for non-cygwin app. */
+ set_disable_master_thread (con.owner == GetCurrentProcessId ());
/* conmode can be tty::restore when non-cygwin app is
exec'ed from login shell. */
- tty::cons_mode conmode = cons_mode_on_close ();
- set_output_mode (conmode, ti, p);
- set_input_mode (conmode, ti, p);
- set_disable_master_thread (con.owner == GetCurrentProcessId ());
+ tty::cons_mode conmode = cons_mode_on_close (p);
+ if (con.curr_output_mode != conmode)
+ set_output_mode (conmode, ti, p);
+ if (con.curr_input_mode != conmode)
+ set_input_mode (conmode, ti, p);
}
/* Return the tty structure associated with a given tty number. If the
@@ -1128,8 +1123,8 @@ fhandler_console::bg_check (int sig, bool dontsignal)
in the same process group. */
if (sig == SIGTTIN && con.curr_input_mode != tty::cygwin)
{
- set_input_mode (tty::cygwin, &tc ()->ti, get_handle_set ());
set_disable_master_thread (false, this);
+ set_input_mode (tty::cygwin, &tc ()->ti, get_handle_set ());
}
if (sig == SIGTTOU && con.curr_output_mode != tty::cygwin)
set_output_mode (tty::cygwin, &tc ()->ti, get_handle_set ());
@@ -1144,6 +1139,15 @@ fhandler_console::read (void *pv, size_t& buflen)
push_process_state process_state (PID_TTYIN);
+ if (get_ttyp ()->input_stopped && is_nonblocking ())
+ {
+ set_errno (EAGAIN);
+ buflen = (size_t) -1;
+ return;
+ }
+ while (get_ttyp ()->input_stopped)
+ cygwait (10);
+
size_t copied_chars = 0;
DWORD timeout = is_nonblocking () ? 0 :
@@ -1836,6 +1840,12 @@ fhandler_console::open (int flags, mode_t)
handle_set.output_handle = h;
release_output_mutex ();
+ if (con.owner == GetCurrentProcessId ())
+ {
+ GetConsoleMode (get_handle (), &con.prev_input_mode);
+ GetConsoleMode (get_output_handle (), &con.prev_output_mode);
+ }
+
wpbuf.init ();
handle_set.input_mutex = input_mutex;
@@ -1881,6 +1891,30 @@ fhandler_console::open (int flags, mode_t)
setenv ("TERM", "cygwin", 1);
}
+ HANDLE h_in = GetStdHandle (STD_INPUT_HANDLE);
+ HANDLE h_out = GetStdHandle (STD_OUTPUT_HANDLE);
+ HANDLE h_err = GetStdHandle (STD_ERROR_HANDLE);
+
+ DWORD dummy;
+ bool in_is_console = GetConsoleMode (h_in, &dummy);
+ bool out_is_console =
+ GetConsoleMode (h_out, &dummy) || GetConsoleMode (h_err, &dummy);
+ if (in_is_console)
+ CloseHandle (h_in);
+
+ if (in_is_console && con.curr_input_mode != tty::cygwin)
+ {
+ prev_input_mode_backup = con.prev_input_mode;
+ GetConsoleMode (get_handle (), &con.prev_input_mode);
+ set_input_mode (tty::cygwin, &get_ttyp ()->ti, &handle_set);
+ }
+ if (out_is_console && con.curr_output_mode != tty::cygwin)
+ {
+ prev_output_mode_backup = con.prev_output_mode;
+ GetConsoleMode (get_output_handle (), &con.prev_output_mode);
+ set_output_mode (tty::cygwin, &get_ttyp ()->ti, &handle_set);
+ }
+
debug_printf ("opened conin$ %p, conout$ %p", get_handle (),
get_output_handle ());
@@ -1975,8 +2009,8 @@ fhandler_console::post_open_setup (int fd)
/* Setting-up console mode for cygwin app started from non-cygwin app. */
if (fd == 0)
{
- set_input_mode (tty::cygwin, &get_ttyp ()->ti, &handle_set);
set_disable_master_thread (false, this);
+ set_input_mode (tty::cygwin, &get_ttyp ()->ti, &handle_set);
}
else if (fd == 1 || fd == 2)
set_output_mode (tty::cygwin, &get_ttyp ()->ti, &handle_set);
@@ -1991,11 +2025,13 @@ fhandler_console::close (int flag)
acquire_output_mutex (mutex_timeout);
- if (shared_console_info[unit] && myself->ppid == 1
- && (dev_t) myself->ctty == get_device ())
+ if (shared_console_info[unit] && (dev_t) myself->ctty == get_device ()
+ && cons_mode_on_close (&handle_set) == tty::restore)
{
- set_output_mode (tty::restore, &get_ttyp ()->ti, &handle_set);
- set_input_mode (tty::restore, &get_ttyp ()->ti, &handle_set);
+ if (con.curr_output_mode != tty::restore)
+ set_output_mode (tty::restore, &get_ttyp ()->ti, &handle_set);
+ if (con.curr_input_mode != tty::restore)
+ set_input_mode (tty::restore, &get_ttyp ()->ti, &handle_set);
set_disable_master_thread (true, this);
}
@@ -2131,6 +2167,7 @@ fhandler_console::ioctl (unsigned int cmd, void *arg)
release_output_mutex ();
return -1;
case FIONREAD:
+ case TIOCINQ:
{
DWORD n;
int ret = 0;
@@ -2183,6 +2220,14 @@ fhandler_console::ioctl (unsigned int cmd, void *arg)
return 0;
}
break;
+ case TCXONC:
+ res = this->tcflow ((int)(intptr_t) arg);
+ release_output_mutex ();
+ return res;
+ case TCFLSH:
+ res = this->tcflush ((int)(intptr_t) arg);
+ release_output_mutex ();
+ return res;
}
release_output_mutex ();
@@ -2215,6 +2260,10 @@ int
fhandler_console::tcsetattr (int a, struct termios const *t)
{
get_ttyp ()->ti = *t;
+ if (con.curr_input_mode == tty::cygwin)
+ set_input_mode (tty::cygwin, t, &handle_set);
+ if (con.curr_output_mode == tty::cygwin)
+ set_output_mode (tty::cygwin, t, &handle_set);
return 0;
}
@@ -2980,7 +3029,12 @@ fhandler_console::char_command (char c)
if (con.args[i] == 1) /* DECCKM */
con.cursor_key_app_mode = (c == 'h');
if (con.args[i] == 9001) /* win32-input-mode (https://github.com/microsoft/terminal/blob/main/doc/specs/%234999%20-%20Improved%20keyboard%20handling%20in%20Conpty.md) */
- set_disable_master_thread (c == 'h', this);
+ {
+ set_disable_master_thread (c == 'h', this);
+ if (con.curr_input_mode == tty::cygwin)
+ set_input_mode (tty::cygwin,
+ &tc ()->ti, get_handle_set ());
+ }
}
/* Call fix_tab_position() if screen has been alternated. */
if (need_fix_tab_position)
@@ -4170,8 +4224,8 @@ fhandler_console::write (const void *vsrc, size_t len)
void
fhandler_console::doecho (const void *str, DWORD len)
{
- bool stopped = get_ttyp ()->output_stopped;
- get_ttyp ()->output_stopped = false;
+ int stopped = get_ttyp ()->output_stopped;
+ get_ttyp ()->output_stopped = 0;
write (str, len);
get_ttyp ()->output_stopped = stopped;
}
@@ -4702,10 +4756,31 @@ fhandler_console::fstat (struct stat *st)
}
tty::cons_mode
-fhandler_console::cons_mode_on_close ()
+fhandler_console::cons_mode_on_close (handle_set_t *p)
{
+ int unit = p->unit;
if (myself->ppid != 1) /* Execed from normal cygwin process. */
return tty::cygwin;
+ if (!process_alive (con.owner)) /* The Master process already died. */
+ return tty::restore;
+ if (con.owner == GetCurrentProcessId ()) /* Master process */
+ return tty::restore;
+
+ PROCESS_BASIC_INFORMATION pbi;
+ NTSTATUS status =
+ NtQueryInformationProcess (GetCurrentProcess (), ProcessBasicInformation,
+ &pbi, sizeof (pbi), NULL);
+ if (NT_SUCCESS (status) && cygwin_pid (con.owner)
+ && !process_alive ((DWORD) pbi.InheritedFromUniqueProcessId))
+ /* Execed from normal cygwin process and the parent has been exited. */
+ return tty::cygwin;
+
return tty::restore; /* otherwise, restore */
}
+
+int
+fhandler_console::tcdrain ()
+{
+ return 0;
+}