fhandler_console::console_state NO_COPY
*fhandler_console::shared_console_info[MAX_CONS_DEV + 1];
+static bool NO_COPY inside_pcon_checked = false;
+static bool NO_COPY inside_pcon = false;
+static int NO_COPY parent_pty;
+
bool NO_COPY fhandler_console::invisible_console;
/* con_ra is shared in the same process.
return 1;
}
+void
+fhandler_console::setup_pcon_hand_over ()
+{
+ /* Prepare for pcon hand over */
+ if (!inside_pcon_checked)
+ for (int i = 0; i < NTTYS; i++)
+ {
+ if (!cygwin_shared->tty[i]->pcon_activated)
+ continue;
+ DWORD owner = cygwin_shared->tty[i]->nat_pipe_owner_pid;
+ if (fhandler_pty_common::get_console_process_id
+ (owner, true, false, false, false))
+ {
+ inside_pcon = true;
+ atexit (fhandler_console::pcon_hand_over_proc);
+ parent_pty = i;
+ break;
+ }
+ }
+ inside_pcon_checked = true;
+}
+
+void
+fhandler_console::pcon_hand_over_proc (void)
+{
+ if (!inside_pcon)
+ return;
+ tty *ttyp = cygwin_shared->tty[parent_pty];
+ char buf[MAX_PATH];
+ shared_name (buf, PIPE_SW_MUTEX, parent_pty);
+ HANDLE mtx = OpenMutex (MAXIMUM_ALLOWED, FALSE, buf);
+ WaitForSingleObject (mtx, INFINITE);
+ ReleaseMutex (mtx);
+ DWORD res = WaitForSingleObject (mtx, INFINITE);
+ if (res == WAIT_OBJECT_0 || res == WAIT_ABANDONED)
+ {
+ DWORD owner = ttyp->nat_pipe_owner_pid;
+ if (owner == GetCurrentProcessId ()
+ || owner == (myself->exec_dwProcessId ?: myself->dwProcessId))
+ fhandler_pty_slave::close_pseudoconsole (ttyp, 0);
+ }
+ else
+ system_printf("Acquiring pcon_ho_mutex failed.");
+ /* Do not release the mutex.
+ Hold onto the mutex until this process completes. */
+}
+
bool
fhandler_console::open_setup (int flags)
{
set_flags ((flags & ~O_TEXT) | O_BINARY);
if (myself->set_ctty (this, flags) && !myself->cygstarted)
- init_console_handler (true);
+ {
+ init_console_handler (true);
+ setup_pcon_hand_over ();
+
+ /* Initialize handle_set */
+ handle_set.input_handle = get_handle ();
+ handle_set.output_handle = get_output_handle ();
+ handle_set.input_mutex = input_mutex;
+ handle_set.output_mutex = output_mutex;
+ handle_set.unit = unit;
+ }
return fhandler_base::open_setup (flags);
}
cygheap->ctty = NULL;
return;
}
+ setup_pcon_hand_over ();
if (!execing)
return;
for (int i = (int) num - 1; i >= 0; i--)
if ((match && list[i] == pid) || (!match && list[i] != pid))
{
+ if (!process_alive (list[i]))
+ continue;
if (!cygwin)
{
res_pri = list[i];
res_pri = stub_only ? p->exec_dwProcessId : list[i];
break;
}
- if (!p && !res && process_alive (list[i]) && stub_only)
+ if (!p && !res && stub_only)
res = list[i];
if (!!p && !res && !stub_only)
res = list[i];
inline static bool
nat_pipe_owner_self (DWORD pid)
{
+ if (pid == GetCurrentProcessId ())
+ return true;
return (pid == (myself->exec_dwProcessId ?: myself->dwProcessId));
}
{
/* Search another native process which attaches to the same console */
DWORD current_pid = myself->exec_dwProcessId ?: myself->dwProcessId;
+ if (ttyp->nat_pipe_owner_pid == GetCurrentProcessId ())
+ current_pid = GetCurrentProcessId ();
switch_to = get_console_process_id (current_pid,
false, true, true, true);
if (!switch_to)
switch_to = get_console_process_id (current_pid,
false, true, false, true);
+ if (!switch_to)
+ switch_to = get_console_process_id (current_pid,
+ false, false, false, false);
}
return switch_to;
}
void
fhandler_pty_slave::close_pseudoconsole (tty *ttyp, DWORD force_switch_to)
{
- DWORD switch_to = get_winpid_to_hand_over (ttyp, force_switch_to);
acquire_attach_mutex (mutex_timeout);
ttyp->previous_code_page = GetConsoleCP ();
ttyp->previous_output_code_page = GetConsoleOutputCP ();
release_attach_mutex ();
if (nat_pipe_owner_self (ttyp->nat_pipe_owner_pid))
{ /* I am owner of the nat pipe. */
+ DWORD switch_to = get_winpid_to_hand_over (ttyp, force_switch_to);
if (switch_to)
{
/* Change pseudo console owner to another process (switch_to). */
if (cons_need_cleanup)
fhandler_console::close_handle_set (&cons_handle_set);
}
+
+void
+fhandler_termios::atexit_func ()
+{
+ fhandler_console::pcon_hand_over_proc ();
+}
virtual void setpgid_aux (pid_t pid) {}
virtual bool need_console_handler () { return false; }
virtual bool need_send_ctrl_c_event () { return true; }
+ static void atexit_func ();
struct ptys_handle_set_t
{
console_unit (int, HANDLE *input_mutex = NULL);
};
+ void setup_pcon_hand_over ();
+ static void pcon_hand_over_proc ();
+
friend tty_min * tty_list::get_cttyp ();
};
friend class fhandler_pty_master;
friend class fhandler_pty_slave;
friend class tty_min;
+ friend class fhandler_console;
};
class tty_list
- Make lockf() return ENOLCK when the number of locks exceeds
MAX_LOCKF_CNT rather than printing a warning message.
Addresses: https://cygwin.com/pipermail/cygwin/2024-October/256528.html
+
+- Make console inherit hand over of pseudo console ownership from
+ parent pty.
+ Addresses: https://cygwin.com/pipermail/cygwin/2024-February/255388.html
ctrl_c_handler(). This insures that setting sigExeced
on Ctrl-C key has been completed. */
init_console_handler (false);
+ fhandler_termios::atexit_func ();
myself.exit (EXITCODE_NOSET);
break;
case _P_WAIT: