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)
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. */
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;
}
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. */
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
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;
}
inline static bool
pcon_pid_self (DWORD pid)
{
- return (pid == myself->exec_dwProcessId);
+ return (pid == (myself->exec_dwProcessId ?: myself->dwProcessId));
}
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);
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. */
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
CloseHandle (pcon_owner);
FreeConsole ();
AttachConsole (get_ttyp ()->pcon_pid);
- init_console_handler (true);
+ init_console_handler (false);
goto skip_create;
}
/* Attach to pseudo console */
FreeConsole ();
AttachConsole (pi.dwProcessId);
- init_console_handler (true);
+ init_console_handler (false);
/* Terminate helper process */
SetEvent (goodbye);
/* 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)
{
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,
{
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))
/* 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;
}
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);
{
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);
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);
+ }
+}