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.cc56
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;
+}