From 054b00d96a81ca1169a1dd2d63d79b7ac03919ac Mon Sep 17 00:00:00 2001 From: Takashi Yano Date: Mon, 21 Feb 2022 22:40:48 +0900 Subject: [PATCH] Cygwin: pty: Encapsulate pty code in tty::setpgid(). - This patch hides complex pty codes in tty::setpgid() to transfer input into the class fhandler_pty_slave by encapsulating it. --- winsup/cygwin/fhandler.h | 2 ++ winsup/cygwin/fhandler_tty.cc | 51 +++++++++++++++++++++++++++++ winsup/cygwin/tty.cc | 60 ++--------------------------------- 3 files changed, 55 insertions(+), 58 deletions(-) diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index 40dab9346..91e5437ca 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -1956,6 +1956,7 @@ class fhandler_termios: public fhandler_base static bool path_iscygexec_w (LPCWSTR n, LPWSTR c); virtual bool is_pty_master_with_pcon () { return false; } virtual void cleanup_before_exit () {} + virtual void setpgid_aux (pid_t pid) {} }; enum ansi_intensity @@ -2400,6 +2401,7 @@ class fhandler_pty_slave: public fhandler_pty_common bool stdin_is_ptys); static void cleanup_for_non_cygwin_app (handle_set_t *p, tty *ttyp, bool stdin_is_ptys); + void setpgid_aux (pid_t pid); }; #define __ptsname(buf, unit) __small_sprintf ((buf), "/dev/pty%d", (unit)) diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc index 10026b995..b9549bba9 100644 --- a/winsup/cygwin/fhandler_tty.cc +++ b/winsup/cygwin/fhandler_tty.cc @@ -4047,3 +4047,54 @@ fhandler_pty_slave::cleanup_for_non_cygwin_app (handle_set_t *p, tty *ttyp, close_pseudoconsole (ttyp); ReleaseMutex (p->pcon_mutex); } + +void +fhandler_pty_slave::setpgid_aux (pid_t pid) +{ + WaitForSingleObject (pcon_mutex, INFINITE); + bool was_pcon_fg = get_ttyp ()->pcon_fg (tc ()->pgid); + bool pcon_fg = get_ttyp ()->pcon_fg (pid); + if (!was_pcon_fg && pcon_fg && get_ttyp ()->switch_to_pcon_in + && get_ttyp ()->pcon_input_state_eq (tty::to_cyg)) + { + WaitForSingleObject (input_mutex, mutex_timeout); + transfer_input (tty::to_nat, get_handle (), get_ttyp (), + input_available_event); + ReleaseMutex (input_mutex); + } + else if (was_pcon_fg && !pcon_fg && get_ttyp ()->switch_to_pcon_in + && get_ttyp ()->pcon_input_state_eq (tty::to_nat)) + { + bool attach_restore = false; + HANDLE from = get_handle_nat (); + if (get_ttyp ()->pcon_activated && get_ttyp ()->pcon_pid + && !get_console_process_id (get_ttyp ()->pcon_pid, true)) + { + HANDLE pcon_owner = + OpenProcess (PROCESS_DUP_HANDLE, FALSE, get_ttyp ()->pcon_pid); + DuplicateHandle (pcon_owner, get_ttyp ()->h_pcon_in, + GetCurrentProcess (), &from, + 0, TRUE, DUPLICATE_SAME_ACCESS); + CloseHandle (pcon_owner); + FreeConsole (); + AttachConsole (get_ttyp ()->pcon_pid); + attach_restore = true; + } + WaitForSingleObject (input_mutex, mutex_timeout); + transfer_input (tty::to_cyg, from, get_ttyp (), input_available_event); + ReleaseMutex (input_mutex); + if (attach_restore) + { + FreeConsole (); + pinfo p (myself->ppid); + if (p) + { + if (!AttachConsole (p->dwProcessId)) + AttachConsole (ATTACH_PARENT_PROCESS); + } + else + AttachConsole (ATTACH_PARENT_PROCESS); + } + } + ReleaseMutex (pcon_mutex); +} diff --git a/winsup/cygwin/tty.cc b/winsup/cygwin/tty.cc index bc5c96e66..25b621227 100644 --- a/winsup/cygwin/tty.cc +++ b/winsup/cygwin/tty.cc @@ -306,65 +306,9 @@ extern DWORD mutex_timeout; /* defined in fhandler_termios.cc */ void tty_min::setpgid (int pid) { - fhandler_pty_slave *ptys = NULL; - cygheap_fdenum cfd (false); - while (cfd.next () >= 0 && ptys == NULL) - if (cfd->get_device () == getntty () - && cfd->get_major () == DEV_PTYS_MAJOR) - ptys = (fhandler_pty_slave *) (fhandler_base *) cfd; + if (::cygheap->ctty) + ::cygheap->ctty->setpgid_aux (pid); - if (ptys) - { - tty *ttyp = (tty *) ptys->tc (); - WaitForSingleObject (ptys->pcon_mutex, INFINITE); - bool was_pcon_fg = ttyp->pcon_fg (pgid); - bool pcon_fg = ttyp->pcon_fg (pid); - if (!was_pcon_fg && pcon_fg && ttyp->switch_to_pcon_in - && ttyp->pcon_input_state_eq (tty::to_cyg)) - { - WaitForSingleObject (ptys->input_mutex, mutex_timeout); - fhandler_pty_slave::transfer_input (tty::to_nat, - ptys->get_handle (), ttyp, - ptys->get_input_available_event ()); - ReleaseMutex (ptys->input_mutex); - } - else if (was_pcon_fg && !pcon_fg && ttyp->switch_to_pcon_in - && ttyp->pcon_input_state_eq (tty::to_nat)) - { - bool attach_restore = false; - HANDLE from = ptys->get_handle_nat (); - if (ttyp->pcon_activated && ttyp->pcon_pid - && !ptys->get_console_process_id (ttyp->pcon_pid, true)) - { - HANDLE pcon_owner = - OpenProcess (PROCESS_DUP_HANDLE, FALSE, ttyp->pcon_pid); - DuplicateHandle (pcon_owner, ttyp->h_pcon_in, - GetCurrentProcess (), &from, - 0, TRUE, DUPLICATE_SAME_ACCESS); - CloseHandle (pcon_owner); - FreeConsole (); - AttachConsole (ttyp->pcon_pid); - attach_restore = true; - } - WaitForSingleObject (ptys->input_mutex, mutex_timeout); - fhandler_pty_slave::transfer_input (tty::to_cyg, from, ttyp, - ptys->get_input_available_event ()); - ReleaseMutex (ptys->input_mutex); - if (attach_restore) - { - FreeConsole (); - pinfo p (myself->ppid); - if (p) - { - if (!AttachConsole (p->dwProcessId)) - AttachConsole (ATTACH_PARENT_PROCESS); - } - else - AttachConsole (ATTACH_PARENT_PROCESS); - } - } - ReleaseMutex (ptys->pcon_mutex); - } pgid = pid; }