diff options
-rw-r--r-- | winsup/cygwin/fhandler.h | 8 | ||||
-rw-r--r-- | winsup/cygwin/fhandler_termios.cc | 3 | ||||
-rw-r--r-- | winsup/cygwin/fhandler_tty.cc | 77 | ||||
-rw-r--r-- | winsup/cygwin/wincap.cc | 12 | ||||
-rw-r--r-- | winsup/cygwin/wincap.h | 2 | ||||
-rw-r--r-- | winsup/utils/mingw/cygwin-console-helper.cc | 2 |
6 files changed, 96 insertions, 8 deletions
diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index 80dd94508..36f64818d 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -1984,6 +1984,7 @@ class fhandler_termios: public fhandler_base virtual void setpgid_aux (pid_t pid) {} virtual bool need_console_handler () { return false; } virtual bool need_send_ctrl_c_event () { return true; } + virtual DWORD get_helper_pid () { return 0; } }; enum ansi_intensity @@ -2343,7 +2344,7 @@ class fhandler_pty_common: public fhandler_termios bool cygwin = false, bool stub_only = false); bool to_be_read_from_nat_pipe (void); - static DWORD attach_console_temporarily (DWORD target_pid); + static DWORD attach_console_temporarily (DWORD target_pid, DWORD helper_pid); static void resume_from_temporarily_attach (DWORD resume_pid); protected: @@ -2472,6 +2473,7 @@ public: HANDLE from_slave_nat; HANDLE output_mutex; tty *ttyp; + DWORD helper_pid; }; private: int pktmode; // non-zero if pty in a packet mode. @@ -2483,6 +2485,9 @@ private: HANDLE to_master, from_master; cygthread *master_fwd_thread; // Master forwarding thread HANDLE thread_param_copied_event; + HANDLE helper_goodbye; + HANDLE helper_h_process; + DWORD helper_pid; public: HANDLE get_echo_handle () const { return echo_r; } @@ -2537,6 +2542,7 @@ public: void get_master_fwd_thread_param (master_fwd_thread_param_t *p); void set_mask_flusho (bool m) { get_ttyp ()->mask_flusho = m; } bool need_send_ctrl_c_event (); + DWORD get_helper_pid () { return helper_pid; } }; class fhandler_dev_null: public fhandler_base diff --git a/winsup/cygwin/fhandler_termios.cc b/winsup/cygwin/fhandler_termios.cc index 735423bf2..328c73fcd 100644 --- a/winsup/cygwin/fhandler_termios.cc +++ b/winsup/cygwin/fhandler_termios.cc @@ -359,7 +359,8 @@ fhandler_termios::process_sigs (char c, tty* ttyp, fhandler_termios *fh) DWORD resume_pid = 0; if (fh && !fh->is_console ()) resume_pid = - fhandler_pty_common::attach_console_temporarily (p->dwProcessId); + fhandler_pty_common::attach_console_temporarily + (p->dwProcessId, fh->get_helper_pid ()); if (fh && p == myself && being_debugged ()) { /* Avoid deadlock in gdb on console. */ fh->tcflush(TCIFLUSH); diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc index 9dfc3c495..825d80666 100644 --- a/winsup/cygwin/fhandler_tty.cc +++ b/winsup/cygwin/fhandler_tty.cc @@ -547,7 +547,8 @@ fhandler_pty_master::accept_input () { /* Slave attaches to a different console than master. Therefore reattach here. */ - DWORD resume_pid = attach_console_temporarily (target_pid); + DWORD resume_pid = + attach_console_temporarily (target_pid, helper_pid); cp_to = GetConsoleCP (); resume_from_temporarily_attach (resume_pid); } @@ -2104,6 +2105,16 @@ fhandler_pty_master::close () get_ttyp ()->stop_fwd_thread = true; WriteFile (to_master_nat, "", 0, &len, NULL); master_fwd_thread->detach (); + if (helper_goodbye) + { + SetEvent (helper_goodbye); + WaitForSingleObject (helper_h_process, INFINITE); + CloseHandle (helper_h_process); + CloseHandle (helper_goodbye); + helper_pid = 0; + helper_h_process = 0; + helper_goodbye = NULL; + } } } @@ -2826,7 +2837,8 @@ fhandler_pty_master::pty_master_fwd_thread (const master_fwd_thread_param_t *p) { /* Slave attaches to a different console than master. Therefore reattach here. */ - DWORD resume_pid = attach_console_temporarily (target_pid); + DWORD resume_pid = + attach_console_temporarily (target_pid, p->helper_pid); cp_from = GetConsoleOutputCP (); resume_from_temporarily_attach (resume_pid); } @@ -3009,6 +3021,57 @@ fhandler_pty_master::setup () goto err; } WaitForSingleObject (thread_param_copied_event, INFINITE); + + if (wincap.has_broken_attach_console () + && _major (myself->ctty) == DEV_CONS_MAJOR + && !(!pinfo (myself->ppid) && getenv ("ConEmuPID"))) + { + HANDLE hello = CreateEvent (&sec_none, true, false, NULL); + HANDLE goodbye = CreateEvent (&sec_none, true, false, NULL); + WCHAR cmd[MAX_PATH]; + path_conv helper ("/bin/cygwin-console-helper.exe"); + size_t len = helper.get_wide_win32_path_len (); + helper.get_wide_win32_path (cmd); + __small_swprintf (cmd + len, L" %p %p", hello, goodbye); + + STARTUPINFOEXW si; + PROCESS_INFORMATION pi; + ZeroMemory (&si, sizeof (si)); + si.StartupInfo.cb = sizeof (STARTUPINFOEXW); + + SIZE_T bytesRequired; + InitializeProcThreadAttributeList (NULL, 1, 0, &bytesRequired); + si.lpAttributeList = (PPROC_THREAD_ATTRIBUTE_LIST) + HeapAlloc (GetProcessHeap (), 0, bytesRequired); + InitializeProcThreadAttributeList (si.lpAttributeList, + 1, 0, &bytesRequired); + HANDLE handles_to_inherit[] = {hello, goodbye}; + UpdateProcThreadAttribute (si.lpAttributeList, + 0, + PROC_THREAD_ATTRIBUTE_HANDLE_LIST, + handles_to_inherit, + sizeof (handles_to_inherit), + NULL, NULL); + if (CreateProcessW (NULL, cmd, &sec_none, &sec_none, + TRUE, EXTENDED_STARTUPINFO_PRESENT, + NULL, NULL, &si.StartupInfo, &pi)) + { + WaitForSingleObject (hello, INFINITE); + CloseHandle (hello); + CloseHandle (pi.hThread); + helper_goodbye = goodbye; + helper_pid = pi.dwProcessId; + helper_h_process = pi.hProcess; + } + else + { + CloseHandle (hello); + CloseHandle (goodbye); + } + DeleteProcThreadAttributeList (si.lpAttributeList); + HeapFree (GetProcessHeap (), 0, si.lpAttributeList); + } + master_fwd_thread = new cygthread (::pty_master_fwd_thread, this, "ptymf"); if (!master_fwd_thread) { @@ -3814,6 +3877,7 @@ fhandler_pty_master::get_master_fwd_thread_param (master_fwd_thread_param_t *p) p->from_slave_nat = from_slave_nat; p->output_mutex = output_mutex; p->ttyp = get_ttyp (); + p->helper_pid = helper_pid; SetEvent (thread_param_copied_event); } @@ -4124,7 +4188,7 @@ fhandler_pty_slave::setpgid_aux (pid_t pid) 0, TRUE, DUPLICATE_SAME_ACCESS); CloseHandle (pcon_owner); DWORD target_pid = get_ttyp ()->nat_pipe_owner_pid; - resume_pid = attach_console_temporarily (target_pid); + resume_pid = attach_console_temporarily (target_pid, 0); attach_restore = true; } else @@ -4170,12 +4234,15 @@ fhandler_pty_slave::release_ownership_of_nat_pipe (tty *ttyp, } DWORD -fhandler_pty_common::attach_console_temporarily (DWORD target_pid) +fhandler_pty_common::attach_console_temporarily (DWORD target_pid, + DWORD helper_pid) { DWORD resume_pid = 0; acquire_attach_mutex (mutex_timeout); pinfo pinfo_resume (myself->ppid); - if (pinfo_resume) + if (helper_pid) + resume_pid = helper_pid; + else if (pinfo_resume) resume_pid = pinfo_resume->dwProcessId; if (!resume_pid) resume_pid = get_console_process_id (myself->dwProcessId, false); diff --git a/winsup/cygwin/wincap.cc b/winsup/cygwin/wincap.cc index 835497cfe..0f0b77de8 100644 --- a/winsup/cygwin/wincap.cc +++ b/winsup/cygwin/wincap.cc @@ -44,6 +44,7 @@ wincaps wincap_7 __attribute__((section (".cygwin_dll_common"), shared)) = { has_tcp_maxrtms:false, has_query_process_handle_info:false, has_con_broken_tabs:false, + has_broken_attach_console:true, }, }; @@ -73,6 +74,7 @@ wincaps wincap_8 __attribute__((section (".cygwin_dll_common"), shared)) = { has_tcp_maxrtms:false, has_query_process_handle_info:true, has_con_broken_tabs:false, + has_broken_attach_console:false, }, }; @@ -102,6 +104,7 @@ wincaps wincap_8_1 __attribute__((section (".cygwin_dll_common"), shared)) = { has_tcp_maxrtms:false, has_query_process_handle_info:true, has_con_broken_tabs:false, + has_broken_attach_console:false, }, }; @@ -131,6 +134,7 @@ wincaps wincap_10_1507 __attribute__((section (".cygwin_dll_common"), shared)) has_tcp_maxrtms:false, has_query_process_handle_info:true, has_con_broken_tabs:false, + has_broken_attach_console:false, }, }; @@ -160,6 +164,7 @@ wincaps wincap_10_1607 __attribute__((section (".cygwin_dll_common"), shared)) has_tcp_maxrtms:true, has_query_process_handle_info:true, has_con_broken_tabs:false, + has_broken_attach_console:false, }, }; @@ -189,6 +194,7 @@ wincaps wincap_10_1703 __attribute__((section (".cygwin_dll_common"), shared)) = has_tcp_maxrtms:true, has_query_process_handle_info:true, has_con_broken_tabs:true, + has_broken_attach_console:false, }, }; @@ -218,6 +224,7 @@ wincaps wincap_10_1709 __attribute__((section (".cygwin_dll_common"), shared)) = has_tcp_maxrtms:true, has_query_process_handle_info:true, has_con_broken_tabs:true, + has_broken_attach_console:false, }, }; @@ -247,6 +254,7 @@ wincaps wincap_10_1803 __attribute__((section (".cygwin_dll_common"), shared)) = has_tcp_maxrtms:true, has_query_process_handle_info:true, has_con_broken_tabs:true, + has_broken_attach_console:false, }, }; @@ -276,6 +284,7 @@ wincaps wincap_10_1809 __attribute__((section (".cygwin_dll_common"), shared)) = has_tcp_maxrtms:true, has_query_process_handle_info:true, has_con_broken_tabs:true, + has_broken_attach_console:false, }, }; @@ -305,6 +314,7 @@ wincaps wincap_10_1903 __attribute__((section (".cygwin_dll_common"), shared)) = has_tcp_maxrtms:true, has_query_process_handle_info:true, has_con_broken_tabs:true, + has_broken_attach_console:false, }, }; @@ -334,6 +344,7 @@ wincaps wincap_10_2004 __attribute__((section (".cygwin_dll_common"), shared)) = has_tcp_maxrtms:true, has_query_process_handle_info:true, has_con_broken_tabs:true, + has_broken_attach_console:false, }, }; @@ -363,6 +374,7 @@ wincaps wincap_11 __attribute__((section (".cygwin_dll_common"), shared)) = { has_tcp_maxrtms:true, has_query_process_handle_info:true, has_con_broken_tabs:false, + has_broken_attach_console:false, }, }; diff --git a/winsup/cygwin/wincap.h b/winsup/cygwin/wincap.h index 8184e7151..818359f94 100644 --- a/winsup/cygwin/wincap.h +++ b/winsup/cygwin/wincap.h @@ -38,6 +38,7 @@ struct wincaps unsigned has_tcp_maxrtms : 1; unsigned has_query_process_handle_info : 1; unsigned has_con_broken_tabs : 1; + unsigned has_broken_attach_console : 1; }; }; @@ -97,6 +98,7 @@ public: bool IMPLEMENT (has_tcp_maxrtms) bool IMPLEMENT (has_query_process_handle_info) bool IMPLEMENT (has_con_broken_tabs) + bool IMPLEMENT (has_broken_attach_console) void disable_case_sensitive_dirs () { diff --git a/winsup/utils/mingw/cygwin-console-helper.cc b/winsup/utils/mingw/cygwin-console-helper.cc index 66004bd15..80d15e3f3 100644 --- a/winsup/utils/mingw/cygwin-console-helper.cc +++ b/winsup/utils/mingw/cygwin-console-helper.cc @@ -6,11 +6,11 @@ main (int argc, char **argv) char *end; if (argc < 3) exit (1); + SetConsoleCtrlHandler (NULL, TRUE); HANDLE h = (HANDLE) strtoull (argv[1], &end, 0); SetEvent (h); if (argc == 4) /* Pseudo console helper mode for PTY */ { - SetConsoleCtrlHandler (NULL, TRUE); HANDLE hPipe = (HANDLE) strtoull (argv[3], &end, 0); char buf[64]; sprintf (buf, "StdHandles=%p,%p\n", |