aboutsummaryrefslogtreecommitdiff
path: root/winsup
diff options
context:
space:
mode:
Diffstat (limited to 'winsup')
-rw-r--r--winsup/cygwin/exceptions.cc3
-rw-r--r--winsup/cygwin/fhandler.h2
-rw-r--r--winsup/cygwin/fhandler_termios.cc20
-rw-r--r--winsup/cygwin/fhandler_tty.cc87
-rw-r--r--winsup/cygwin/sigproc.cc3
5 files changed, 65 insertions, 50 deletions
diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc
index 070e52e..f946bed 100644
--- a/winsup/cygwin/exceptions.cc
+++ b/winsup/cygwin/exceptions.cc
@@ -1157,6 +1157,9 @@ ctrl_c_handler (DWORD type)
tty_min *t = cygwin_shared->tty.get_cttyp ();
+ if (!t)
+ return TRUE;
+
/* If process group leader is non-cygwin process or not exist,
send signal to myself. */
pinfo pi (t->getpgid ());
diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index abd62d7..7646f09 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -2409,6 +2409,8 @@ class fhandler_pty_slave: public fhandler_pty_common
static void cleanup_for_non_cygwin_app (handle_set_t *p, tty *ttyp,
bool stdin_is_ptys);
void setpgid_aux (pid_t pid);
+ static void close_pseudoconsole_if_necessary (tty *ttyp,
+ fhandler_termios *fh);
};
#define __ptsname(buf, unit) __small_sprintf ((buf), "/dev/pty%d", (unit))
diff --git a/winsup/cygwin/fhandler_termios.cc b/winsup/cygwin/fhandler_termios.cc
index f83770e..0948420 100644
--- a/winsup/cygwin/fhandler_termios.cc
+++ b/winsup/cygwin/fhandler_termios.cc
@@ -357,6 +357,7 @@ fhandler_termios::process_sigs (char c, tty* ttyp, fhandler_termios *fh)
which the target process is attaching before sending the
CTRL_C_EVENT. After sending the event, reattach to the
console to which the process was previously attached. */
+ bool console_exists = fhandler_console::exists ();
pinfo pinfo_resume = pinfo (myself->ppid);
DWORD resume_pid = 0;
if (pinfo_resume)
@@ -364,11 +365,12 @@ fhandler_termios::process_sigs (char c, tty* ttyp, fhandler_termios *fh)
else
resume_pid = fhandler_pty_common::get_console_process_id
(myself->dwProcessId, false);
- if (resume_pid && fh && !fh->is_console ())
+ if ((!console_exists || resume_pid) && fh && !fh->is_console ())
{
FreeConsole ();
AttachConsole (p->dwProcessId);
- init_console_handler (true);
+ init_console_handler (::cygheap->ctty
+ && ::cygheap->ctty->is_console ());
}
if (fh && p == myself && being_debugged ())
{ /* Avoid deadlock in gdb on console. */
@@ -388,11 +390,19 @@ fhandler_termios::process_sigs (char c, tty* ttyp, fhandler_termios *fh)
GenerateConsoleCtrlEvent (CTRL_C_EVENT, 0);
ctrl_c_event_sent = true;
}
- if (resume_pid && fh && !fh->is_console ())
+ if ((!console_exists || resume_pid) && fh && !fh->is_console ())
{
+ /* If a process on pseudo console is killed by Ctrl-C,
+ this process may take over the ownership of the
+ pseudo console because this process attached to it
+ before sending CTRL_C_EVENT. In this case, closing
+ pseudo console is necessary. */
+ fhandler_pty_slave::close_pseudoconsole_if_necessary (ttyp, fh);
FreeConsole ();
- AttachConsole (resume_pid);
- init_console_handler (true);
+ if (resume_pid && console_exists)
+ AttachConsole (resume_pid);
+ init_console_handler (::cygheap->ctty
+ && ::cygheap->ctty->is_console ());
}
need_discard_input = true;
}
diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc
index dde77cc..7b099dc 100644
--- a/winsup/cygwin/fhandler_tty.cc
+++ b/winsup/cygwin/fhandler_tty.cc
@@ -537,7 +537,8 @@ fhandler_pty_master::accept_input ()
resume_pid = pinfo_resume->dwProcessId;
else
resume_pid = get_console_process_id (myself->dwProcessId, false);
- if (target_pid && resume_pid)
+ bool console_exists = fhandler_console::exists ();
+ if (target_pid && (resume_pid || !console_exists))
{
/* Slave attaches to a different console than master.
Therefore reattach here. */
@@ -546,8 +547,9 @@ fhandler_pty_master::accept_input ()
AttachConsole (target_pid);
cp_to = GetConsoleCP ();
FreeConsole ();
- AttachConsole (resume_pid);
- init_console_handler (true);
+ if (resume_pid && console_exists)
+ AttachConsole (resume_pid);
+ init_console_handler (false);
release_attach_mutex ();
}
else
@@ -1029,12 +1031,12 @@ fhandler_pty_slave::close ()
if (!ForceCloseHandle (get_handle_nat ()))
termios_printf ("CloseHandle (get_handle_nat ()<%p>), %E",
get_handle_nat ());
- if ((unsigned) myself->ctty == FHDEV (DEV_PTYS_MAJOR, get_minor ()))
- fhandler_console::free_console (); /* assumes that we are the last pty closer */
fhandler_pty_common::close ();
if (!ForceCloseHandle (output_mutex))
termios_printf ("CloseHandle (output_mutex<%p>), %E", output_mutex);
- get_ttyp ()->invisible_console_pid = 0;
+ if (get_ttyp ()->invisible_console_pid
+ && !pinfo (get_ttyp ()->invisible_console_pid))
+ get_ttyp ()->invisible_console_pid = 0;
return 0;
}
@@ -1122,7 +1124,7 @@ pcon_pid_alive (DWORD pid)
inline static bool
pcon_pid_self (DWORD pid)
{
- return (pid == myself->exec_dwProcessId);
+ return (pid == (myself->exec_dwProcessId ?: myself->dwProcessId));
}
void
@@ -1240,14 +1242,14 @@ fhandler_pty_slave::reset_switch_to_pcon (void)
0, TRUE, DUPLICATE_SAME_ACCESS);
FreeConsole ();
AttachConsole (get_ttyp ()->pcon_pid);
- init_console_handler (true);
+ init_console_handler (false);
WaitForSingleObject (input_mutex, mutex_timeout);
transfer_input (tty::to_cyg, h_pcon_in, get_ttyp (),
input_available_event);
ReleaseMutex (input_mutex);
FreeConsole ();
AttachConsole (resume_pid);
- init_console_handler (true);
+ init_console_handler (false);
CloseHandle (h_pcon_in);
}
CloseHandle (pcon_owner);
@@ -2839,7 +2841,8 @@ fhandler_pty_master::pty_master_fwd_thread (const master_fwd_thread_param_t *p)
resume_pid = pinfo_resume->dwProcessId;
else
resume_pid = get_console_process_id (myself->dwProcessId, false);
- if (target_pid && resume_pid)
+ bool console_exists = fhandler_console::exists ();
+ if (target_pid && (resume_pid || !console_exists))
{
/* Slave attaches to a different console than master.
Therefore reattach here. */
@@ -2848,8 +2851,9 @@ fhandler_pty_master::pty_master_fwd_thread (const master_fwd_thread_param_t *p)
AttachConsole (target_pid);
cp_from = GetConsoleOutputCP ();
FreeConsole ();
- AttachConsole (resume_pid);
- init_console_handler (true);
+ if (resume_pid && console_exists)
+ AttachConsole (resume_pid);
+ init_console_handler (false);
release_attach_mutex ();
}
else
@@ -3272,7 +3276,7 @@ fhandler_pty_slave::setup_pseudoconsole (bool nopcon)
CloseHandle (pcon_owner);
FreeConsole ();
AttachConsole (get_ttyp ()->pcon_pid);
- init_console_handler (true);
+ init_console_handler (false);
goto skip_create;
}
@@ -3396,7 +3400,7 @@ fhandler_pty_slave::setup_pseudoconsole (bool nopcon)
/* Attach to pseudo console */
FreeConsole ();
AttachConsole (pi.dwProcessId);
- init_console_handler (true);
+ init_console_handler (false);
/* Terminate helper process */
SetEvent (goodbye);
@@ -3531,6 +3535,8 @@ fhandler_pty_slave::close_pseudoconsole (tty *ttyp, DWORD force_switch_to)
/* Search another process which attaches to the pseudo console */
DWORD current_pid = myself->exec_dwProcessId ?: myself->dwProcessId;
switch_to = get_console_process_id (current_pid, false, true, true);
+ if (!switch_to)
+ switch_to = get_console_process_id (current_pid, false, true, false);
}
if (ttyp->pcon_activated)
{
@@ -3579,27 +3585,17 @@ fhandler_pty_slave::close_pseudoconsole (tty *ttyp, DWORD force_switch_to)
ttyp->h_pcon_out = new_pcon_out;
FreeConsole ();
pinfo p (myself->ppid);
- if (p)
- {
- if (!AttachConsole (p->dwProcessId))
- AttachConsole (ATTACH_PARENT_PROCESS);
- }
- else
+ if (!p || !AttachConsole (p->dwProcessId))
AttachConsole (ATTACH_PARENT_PROCESS);
- init_console_handler (true);
+ init_console_handler (false);
}
else
{ /* Close pseudo console */
FreeConsole ();
pinfo p (myself->ppid);
- if (p)
- {
- if (!AttachConsole (p->dwProcessId))
- AttachConsole (ATTACH_PARENT_PROCESS);
- }
- else
+ if (!p || !AttachConsole (p->dwProcessId))
AttachConsole (ATTACH_PARENT_PROCESS);
- init_console_handler (true);
+ init_console_handler (false);
/* Reconstruct pseudo console handler container here for close */
HPCON_INTERNAL *hp =
(HPCON_INTERNAL *) HeapAlloc (GetProcessHeap (), 0,
@@ -3621,14 +3617,9 @@ fhandler_pty_slave::close_pseudoconsole (tty *ttyp, DWORD force_switch_to)
{
FreeConsole ();
pinfo p (myself->ppid);
- if (p)
- {
- if (!AttachConsole (p->dwProcessId))
- AttachConsole (ATTACH_PARENT_PROCESS);
- }
- else
+ if (!p || !AttachConsole (p->dwProcessId))
AttachConsole (ATTACH_PARENT_PROCESS);
- init_console_handler (true);
+ init_console_handler (false);
}
}
else if (pcon_pid_self (ttyp->pcon_pid))
@@ -3795,7 +3786,7 @@ fhandler_pty_slave::create_invisible_console ()
/* Detach from console device and create new invisible console. */
FreeConsole();
fhandler_console::need_invisible (true);
- init_console_handler (true);
+ init_console_handler (false);
get_ttyp ()->need_invisible_console = false;
get_ttyp ()->invisible_console_pid = myself->pid;
}
@@ -4102,7 +4093,7 @@ fhandler_pty_slave::setpgid_aux (pid_t pid)
CloseHandle (pcon_owner);
FreeConsole ();
AttachConsole (get_ttyp ()->pcon_pid);
- init_console_handler (true);
+ init_console_handler (false);
attach_restore = true;
}
WaitForSingleObject (input_mutex, mutex_timeout);
@@ -4112,14 +4103,9 @@ fhandler_pty_slave::setpgid_aux (pid_t pid)
{
FreeConsole ();
pinfo p (myself->ppid);
- if (p)
- {
- if (!AttachConsole (p->dwProcessId))
- AttachConsole (ATTACH_PARENT_PROCESS);
- }
- else
+ if (!p || !AttachConsole (p->dwProcessId))
AttachConsole (ATTACH_PARENT_PROCESS);
- init_console_handler (true);
+ init_console_handler (false);
}
}
ReleaseMutex (pcon_mutex);
@@ -4135,3 +4121,16 @@ fhandler_pty_master::need_send_ctrl_c_event ()
return !(to_be_read_from_pcon () && get_ttyp ()->pcon_activated
&& get_ttyp ()->pcon_input_state == tty::to_nat);
}
+
+void
+fhandler_pty_slave::close_pseudoconsole_if_necessary (tty *ttyp,
+ fhandler_termios *fh)
+{
+ if (fh->get_major () == DEV_PTYM_MAJOR && ttyp->pcon_activated)
+ {
+ fhandler_pty_master *ptym = (fhandler_pty_master *) fh;
+ WaitForSingleObject (ptym->pcon_mutex, INFINITE);
+ close_pseudoconsole (ttyp);
+ ReleaseMutex (ptym->pcon_mutex);
+ }
+}
diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc
index 4d7d273..edfdffd 100644
--- a/winsup/cygwin/sigproc.cc
+++ b/winsup/cygwin/sigproc.cc
@@ -1392,7 +1392,8 @@ wait_sig (VOID *)
sig_held = true;
break;
case __SIGSETPGRP:
- init_console_handler (true);
+ init_console_handler (::cygheap->ctty
+ && ::cygheap->ctty->is_console ());
break;
case __SIGTHREADEXIT:
{