diff options
Diffstat (limited to 'winsup/cygwin/fhandler/console.cc')
-rw-r--r-- | winsup/cygwin/fhandler/console.cc | 56 |
1 files changed, 49 insertions, 7 deletions
diff --git a/winsup/cygwin/fhandler/console.cc b/winsup/cygwin/fhandler/console.cc index f162698..2e19e0d 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; @@ -932,7 +932,7 @@ fhandler_console::cleanup_for_non_cygwin_app (handle_set_t *p) /* Cleaning-up console mode for non-cygwin app. */ /* conmode can be tty::restore when non-cygwin app is exec'ed from login shell. */ - tty::cons_mode conmode = cons_mode_on_close (); + tty::cons_mode conmode = cons_mode_on_close (p); set_output_mode (conmode, ti, p); set_input_mode (conmode, ti, p); set_disable_master_thread (con.owner == GetCurrentProcessId ()); @@ -1144,6 +1144,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 : @@ -1991,8 +2000,9 @@ 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] && con.curr_input_mode != tty::restore + && (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); @@ -2131,6 +2141,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 +2194,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 +2234,8 @@ int fhandler_console::tcsetattr (int a, struct termios const *t) { get_ttyp ()->ti = *t; + set_input_mode (tty::cygwin, t, &handle_set); + set_output_mode (tty::cygwin, t, &handle_set); return 0; } @@ -4170,8 +4191,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 +4723,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) + && !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; +} |