From c8568e060566b623e5c20be7692882bdc16a4862 Mon Sep 17 00:00:00 2001 From: Mitchell Hentges Date: Thu, 10 Feb 2022 10:38:08 -0500 Subject: [PATCH 1/9] Cygwin: console: Maintain ENABLE_(INSERT|QUICK_EDIT)_MODE flags. - Currently, ENABLE_INSERT_MODE and ENABLE_QUICK_EDIT_MODE are cleared if cygwin is started in console. These flags will not be recovered even when exiting from cygwin. Also note that if ENABLE_EXTENDED_FLAGS is once unset, then the flag ENABLE_QUICK_EDIT_MODE it's associated with will no longer be preserved. Unfortunately, we're accidentally stepping on this in fhandler_console::set_input_mode(). This patch solves this by carrying forward these flags in the place where it had been ignoring them. Since the previous behaviour of leaving these flags unset would essentially maintain their existing state, adding the carry-over of the flags now should not alter console behaviour. --- winsup/cygwin/fhandler_console.cc | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/winsup/cygwin/fhandler_console.cc b/winsup/cygwin/fhandler_console.cc index da1d2e80f6..7d59dd24a9 100644 --- a/winsup/cygwin/fhandler_console.cc +++ b/winsup/cygwin/fhandler_console.cc @@ -458,16 +458,18 @@ void fhandler_console::set_input_mode (tty::cons_mode m, const termios *t, const handle_set_t *p) { - DWORD flags = 0, oflags; + DWORD oflags; WaitForSingleObject (p->input_mutex, mutex_timeout); GetConsoleMode (p->input_handle, &oflags); + DWORD flags = oflags + & (ENABLE_EXTENDED_FLAGS | ENABLE_INSERT_MODE | ENABLE_QUICK_EDIT_MODE); switch (m) { case tty::restore: - flags = ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT; + flags |= ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT; break; case tty::cygwin: - flags = ENABLE_WINDOW_INPUT; + flags |= ENABLE_WINDOW_INPUT; if (wincap.has_con_24bit_colors () && !con_is_legacy) flags |= ENABLE_VIRTUAL_TERMINAL_INPUT; else From 4f54570fab07be5947b973af652b6183f3b29fcd Mon Sep 17 00:00:00 2001 From: Takashi Yano Date: Thu, 10 Feb 2022 16:53:47 +0900 Subject: [PATCH 2/9] Cygwin: pty, console: Fix Ctrl-C handling for non-cygwin apps. - Currently, if cat is started from cmd.exe which is started in cygwin console, Ctrl-C terminates not only cat but also cmd.exe. This also happens in pty in which pseudo console is disabled. This patch fixes the issue. --- winsup/cygwin/fhandler_console.cc | 28 +++++++++++++++++++++++ winsup/cygwin/fhandler_termios.cc | 38 +++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) diff --git a/winsup/cygwin/fhandler_console.cc b/winsup/cygwin/fhandler_console.cc index 7d59dd24a9..996561b93f 100644 --- a/winsup/cygwin/fhandler_console.cc +++ b/winsup/cygwin/fhandler_console.cc @@ -238,6 +238,33 @@ fhandler_console::cons_master_thread (handle_set_t *p, tty *ttyp) char c = (char) wc; bool processed = false; termios &ti = ttyp->ti; + pinfo pi (ttyp->getpgid ()); + if (pi && pi->ctty == ttyp->ntty + && (pi->process_state & PID_NOTCYGWIN) + && input_rec[i].EventType == KEY_EVENT && c == '\003') + { + bool not_a_sig = false; + if (!CCEQ (ti.c_cc[VINTR], c) + && !CCEQ (ti.c_cc[VQUIT], c) + && !CCEQ (ti.c_cc[VSUSP], c)) + not_a_sig = true; + if (input_rec[i].Event.KeyEvent.bKeyDown) + { + /* CTRL_C_EVENT does not work for the process started with + CREATE_NEW_PROCESS_GROUP flag, so send CTRL_BREAK_EVENT + instead. */ + if (pi->process_state & PID_NEW_PG) + GenerateConsoleCtrlEvent (CTRL_BREAK_EVENT, + pi->dwProcessId); + else + GenerateConsoleCtrlEvent (CTRL_C_EVENT, 0); + if (not_a_sig) + goto skip_writeback; + } + processed = true; + if (not_a_sig) + goto remove_record; + } switch (input_rec[i].EventType) { case KEY_EVENT: @@ -310,6 +337,7 @@ fhandler_console::cons_master_thread (handle_set_t *p, tty *ttyp) processed = true; break; } +remove_record: if (processed) { /* Remove corresponding record. */ memmove (input_rec + i, input_rec + i + 1, diff --git a/winsup/cygwin/fhandler_termios.cc b/winsup/cygwin/fhandler_termios.cc index 3461d17856..fe10215202 100644 --- a/winsup/cygwin/fhandler_termios.cc +++ b/winsup/cygwin/fhandler_termios.cc @@ -147,6 +147,8 @@ tty_min::kill_pgrp (int sig) _pinfo *p = pids[i]; if (!p || !p->exists () || p->ctty != ntty || p->pgid != pgid) continue; + if (p->process_state & PID_NOTCYGWIN) + continue; if (p == myself) killself = sig != __SIGSETPGRP && !exit_state; else @@ -326,6 +328,42 @@ fhandler_termios::line_edit (const char *rptr, size_t nread, termios& ti, if (ti.c_iflag & ISTRIP) c &= 0x7f; + winpids pids ((DWORD) 0); + if (get_ttyp ()->pcon_input_state_eq (tty::to_nat)) + { + bool need_discard_input = false; + for (unsigned i = 0; i < pids.npids; i++) + { + _pinfo *p = pids[i]; + if (c == '\003' && p && p->ctty == tc ()->ntty + && p->pgid == tc ()->getpgid () + && (p->process_state & PID_NOTCYGWIN)) + { + /* CTRL_C_EVENT does not work for the process started with + CREATE_NEW_PROCESS_GROUP flag, so send CTRL_BREAK_EVENT + instead. */ + if (p->process_state & PID_NEW_PG) + GenerateConsoleCtrlEvent (CTRL_BREAK_EVENT, + p->dwProcessId); + else + GenerateConsoleCtrlEvent (CTRL_C_EVENT, 0); + need_discard_input = true; + } + } + if (need_discard_input + && !CCEQ (ti.c_cc[VINTR], c) + && !CCEQ (ti.c_cc[VQUIT], c) + && !CCEQ (ti.c_cc[VSUSP], c)) + { + if (!(ti.c_lflag & NOFLSH)) + { + eat_readahead (-1); + discard_input (); + } + ti.c_lflag &= ~FLUSHO; + continue; + } + } if (ti.c_lflag & ISIG) { int sig; From 69e9facbd4909e77bc1f991076867740eb07ad3a Mon Sep 17 00:00:00 2001 From: Takashi Yano Date: Sat, 12 Feb 2022 17:51:55 +0900 Subject: [PATCH 3/9] Cygwin: pty: Pass Ctrl-Z (EOF) to non-cygwin apps with disable_pcon. - Previously, non-cygwin app running in pty started without pseudo console support was suspended by Ctrl-Z rather than sending EOF. Even worse, suspended app could not be resumed by fg command. With this patch, Ctrl-Z (EOF for non-cygwin apps) is passed to non-cygwin app instead of suspending that app. This patch also handles Ctrl-\ (QUIT) and Ctrl-D (EOF) as well. --- winsup/cygwin/fhandler_termios.cc | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/winsup/cygwin/fhandler_termios.cc b/winsup/cygwin/fhandler_termios.cc index fe10215202..b935a70bc3 100644 --- a/winsup/cygwin/fhandler_termios.cc +++ b/winsup/cygwin/fhandler_termios.cc @@ -329,6 +329,7 @@ fhandler_termios::line_edit (const char *rptr, size_t nread, termios& ti, if (ti.c_iflag & ISTRIP) c &= 0x7f; winpids pids ((DWORD) 0); + bool need_check_sigs = get_ttyp ()->pcon_input_state_eq (tty::to_cyg); if (get_ttyp ()->pcon_input_state_eq (tty::to_nat)) { bool need_discard_input = false; @@ -349,11 +350,15 @@ fhandler_termios::line_edit (const char *rptr, size_t nread, termios& ti, GenerateConsoleCtrlEvent (CTRL_C_EVENT, 0); need_discard_input = true; } + if (p->ctty == get_ttyp ()->ntty + && p->pgid == get_ttyp ()->getpgid () && !p->cygstarted) + need_check_sigs = true; } - if (need_discard_input - && !CCEQ (ti.c_cc[VINTR], c) + if (!CCEQ (ti.c_cc[VINTR], c) && !CCEQ (ti.c_cc[VQUIT], c) && !CCEQ (ti.c_cc[VSUSP], c)) + need_check_sigs = false; + if (need_discard_input && !need_check_sigs) { if (!(ti.c_lflag & NOFLSH)) { @@ -364,7 +369,7 @@ fhandler_termios::line_edit (const char *rptr, size_t nread, termios& ti, continue; } } - if (ti.c_lflag & ISIG) + if ((ti.c_lflag & ISIG) && need_check_sigs) { int sig; if (CCEQ (ti.c_cc[VINTR], c)) @@ -469,7 +474,7 @@ fhandler_termios::line_edit (const char *rptr, size_t nread, termios& ti, } continue; } - else if (CCEQ (ti.c_cc[VEOF], c)) + else if (CCEQ (ti.c_cc[VEOF], c) && need_check_sigs) { termios_printf ("EOF"); accept_input (); From 9d5dfc73fd91cffbd4b4de0cb969e6e474072de4 Mon Sep 17 00:00:00 2001 From: Takashi Yano Date: Thu, 10 Feb 2022 17:22:11 +0900 Subject: [PATCH 4/9] Cygwin: pty: Prevent deadlock on echo output. - If the slave process writes a lot of text output, doecho() can cause deadlock. This is because output_mutex is held in slave:: write() and if WriteFile() is blocked due to pipe full, doecho() tries to acquire output_mutex and gets into deadlock. With this patch, the deadlock is prevented on the sacrifice of atomicity of doecho(). --- winsup/cygwin/fhandler_tty.cc | 2 -- 1 file changed, 2 deletions(-) diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc index 10566ac918..c1c2c1d1b9 100644 --- a/winsup/cygwin/fhandler_tty.cc +++ b/winsup/cygwin/fhandler_tty.cc @@ -496,11 +496,9 @@ void fhandler_pty_master::doecho (const void *str, DWORD len) { ssize_t towrite = len; - acquire_output_mutex (mutex_timeout); if (!process_opost_output (echo_w, str, towrite, true, get_ttyp (), is_nonblocking ())) termios_printf ("Write to echo pipe failed, %E"); - release_output_mutex (); } int From 223769c731c7d83b254c911b4fa5c671ebe79e64 Mon Sep 17 00:00:00 2001 From: Takashi Yano Date: Thu, 10 Feb 2022 17:47:51 +0900 Subject: [PATCH 5/9] Cygwin: pty: Revise the code to wait for completion of forwarding. - With this patch, the code to wait for completion of forwarding of output from non-cygwin app is revised so that it can more reliably detect the completion. --- winsup/cygwin/fhandler_tty.cc | 5 ++++- winsup/cygwin/tty.cc | 11 ++++++----- winsup/cygwin/tty.h | 3 ++- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc index c1c2c1d1b9..6217883214 100644 --- a/winsup/cygwin/fhandler_tty.cc +++ b/winsup/cygwin/fhandler_tty.cc @@ -1122,7 +1122,7 @@ fhandler_pty_slave::reset_switch_to_pcon (void) if (WaitForSingleObject (h_gdb_process, 0) == WAIT_TIMEOUT) { if (isHybrid) - get_ttyp ()->wait_pcon_fwd (false); + get_ttyp ()->wait_pcon_fwd (); } else { @@ -2717,6 +2717,9 @@ fhandler_pty_master::pty_master_fwd_thread (const master_fwd_thread_param_t *p) for (;;) { p->ttyp->pcon_last_time = GetTickCount (); + DWORD n; + p->ttyp->pcon_fwd_not_empty = + ::bytes_available (n, p->from_slave_nat) && n; if (!ReadFile (p->from_slave_nat, outbuf, NT_MAX_PATH, &rlen, NULL)) { termios_printf ("ReadFile for forwarding failed, %E"); diff --git a/winsup/cygwin/tty.cc b/winsup/cygwin/tty.cc index 7895288562..da75b8dd2e 100644 --- a/winsup/cygwin/tty.cc +++ b/winsup/cygwin/tty.cc @@ -240,6 +240,7 @@ tty::init () pcon_pid = 0; term_code_page = 0; pcon_last_time = 0; + pcon_fwd_not_empty = false; pcon_start = false; pcon_start_pid = 0; pcon_cap_checked = false; @@ -367,7 +368,7 @@ tty_min::setpgid (int pid) } void -tty::wait_pcon_fwd (bool init) +tty::wait_pcon_fwd () { /* The forwarding in pseudo console sometimes stops for 16-32 msec even if it already has data to transfer. @@ -377,11 +378,11 @@ tty::wait_pcon_fwd (bool init) thread when the last data is transfered. */ const int sleep_in_pcon = 16; const int time_to_wait = sleep_in_pcon * 2 + 1/* margine */; - if (init) - pcon_last_time = GetTickCount (); - while (GetTickCount () - pcon_last_time < time_to_wait) + int elapsed; + while (pcon_fwd_not_empty + || (elapsed = GetTickCount () - pcon_last_time) < time_to_wait) { - int tw = time_to_wait - (GetTickCount () - pcon_last_time); + int tw = pcon_fwd_not_empty ? 10 : (time_to_wait - elapsed); cygwait (tw); } } diff --git a/winsup/cygwin/tty.h b/winsup/cygwin/tty.h index 519d7c0d59..2cd12a665f 100644 --- a/winsup/cygwin/tty.h +++ b/winsup/cygwin/tty.h @@ -116,6 +116,7 @@ class tty: public tty_min DWORD pcon_pid; UINT term_code_page; DWORD pcon_last_time; + bool pcon_fwd_not_empty; HANDLE h_pcon_write_pipe; HANDLE h_pcon_condrv_reference; HANDLE h_pcon_conhost_process; @@ -166,7 +167,7 @@ class tty: public tty_min void set_master_ctl_closed () {master_pid = -1;} static void __stdcall create_master (int); static void __stdcall init_session (); - void wait_pcon_fwd (bool init = true); + void wait_pcon_fwd (); bool pcon_input_state_eq (xfer_dir x) { return pcon_input_state == x; } bool pcon_fg (pid_t pgid); friend class fhandler_pty_common; From fa46a437767f1ac66742a41f56b4e4b1f052ccef Mon Sep 17 00:00:00 2001 From: Takashi Yano Date: Sun, 13 Feb 2022 02:16:32 +0900 Subject: [PATCH 6/9] Cygwin: pty: Discard input in from_master_nat pipe on signal as well. - Currently, pty discards input only in from_master pipe on signal. Due to this, if pty is started without pseudo console support and start a non-cygwin process from cmd.exe, type adhead input is not discarded on signals such as Ctrl-C. This patch fixes the issue. --- winsup/cygwin/fhandler_tty.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc index 6217883214..d80b5304a4 100644 --- a/winsup/cygwin/fhandler_tty.cc +++ b/winsup/cygwin/fhandler_tty.cc @@ -438,6 +438,9 @@ fhandler_pty_master::discard_input () while (::bytes_available (bytes_in_pipe, from_master) && bytes_in_pipe) ReadFile (from_master, buf, sizeof(buf), &n, NULL); ResetEvent (input_available_event); + if (!get_ttyp ()->pcon_activated) + while (::bytes_available (bytes_in_pipe, from_master_nat) && bytes_in_pipe) + ReadFile (from_master_nat, buf, sizeof(buf), &n, NULL); get_ttyp ()->discard_input = true; ReleaseMutex (input_mutex); } From 9b90fed7c54215a1b958806f11825650e6196aa6 Mon Sep 17 00:00:00 2001 From: Takashi Yano Date: Sun, 13 Feb 2022 05:12:18 +0900 Subject: [PATCH 7/9] Cygwin: pty: Fix a bug in tty_min::segpgid(). - In tty_min::setpgid(), a pointer to fhandler instance is casted to fhandler_pty_slave and accessed even if terminal is not a pty slave. This patch fixes the issue. --- winsup/cygwin/tty.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/winsup/cygwin/tty.cc b/winsup/cygwin/tty.cc index da75b8dd2e..c0015aceb4 100644 --- a/winsup/cygwin/tty.cc +++ b/winsup/cygwin/tty.cc @@ -309,7 +309,8 @@ 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 ()) + if (cfd->get_device () == getntty () + && cfd->get_major () == DEV_PTYS_MAJOR) ptys = (fhandler_pty_slave *) (fhandler_base *) cfd; if (ptys) From f5649ceeaccfd53b55127819a142cf20f15a2a3e Mon Sep 17 00:00:00 2001 From: Takashi Yano Date: Sun, 13 Feb 2022 12:03:45 +0900 Subject: [PATCH 8/9] Cygwin: console: Fix console mode for non-cygwin inferior of GDB. - Currently, there is no chance to change console mode for non-cygwin inferior of GDB. With this patch, the console mode is changed to tty::native in CreateProcess() and ContinueDebugEvent() hooked in fhandler_console. --- winsup/cygwin/fhandler.h | 2 + winsup/cygwin/fhandler_console.cc | 39 +++++++++ winsup/cygwin/fhandler_tty.cc | 128 +++++++++++++++--------------- 3 files changed, 107 insertions(+), 62 deletions(-) diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index 4226bfd695..c2d91ea117 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -1941,6 +1941,8 @@ class fhandler_termios: public fhandler_base fh->copy_from (this); return fh; } + static bool path_iscygexec_a (LPCSTR n, LPSTR c); + static bool path_iscygexec_w (LPCWSTR n, LPWSTR c); }; enum ansi_intensity diff --git a/winsup/cygwin/fhandler_console.cc b/winsup/cygwin/fhandler_console.cc index 996561b93f..17de688f00 100644 --- a/winsup/cygwin/fhandler_console.cc +++ b/winsup/cygwin/fhandler_console.cc @@ -32,6 +32,7 @@ details. */ #include "sync.h" #include "child_info.h" #include "cygwait.h" +#include "winf.h" /* Don't make this bigger than NT_MAX_PATH as long as the temporary buffer is allocated using tmp_pathbuf!!! */ @@ -3585,10 +3586,32 @@ set_console_title (char *title) debug_printf ("title '%W'", buf); } +static bool NO_COPY gdb_inferior_noncygwin = false; +static void +set_console_mode_to_native () +{ + cygheap_fdenum cfd (false); + while (cfd.next () >= 0) + if (cfd->get_major () == DEV_CONS_MAJOR) + { + fhandler_console *cons = (fhandler_console *) (fhandler_base *) cfd; + if (cons->get_device () == cons->tc ()->getntty ()) + { + termios *cons_ti = &((tty *) cons->tc ())->ti; + fhandler_console::set_input_mode (tty::native, cons_ti, + cons->get_handle_set ()); + fhandler_console::set_output_mode (tty::native, cons_ti, + cons->get_handle_set ()); + break; + } + } +} + #define DEF_HOOK(name) static __typeof__ (name) *name##_Orig /* CreateProcess() is hooked for GDB etc. */ DEF_HOOK (CreateProcessA); DEF_HOOK (CreateProcessW); +DEF_HOOK (ContinueDebugEvent); static BOOL WINAPI CreateProcessA_Hooked @@ -3598,6 +3621,9 @@ CreateProcessA_Hooked { if (f & (DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS)) mutex_timeout = 0; /* to avoid deadlock in GDB */ + gdb_inferior_noncygwin = !fhandler_termios::path_iscygexec_a (n, c); + if (gdb_inferior_noncygwin) + set_console_mode_to_native (); return CreateProcessA_Orig (n, c, pa, ta, inh, f, e, d, si, pi); } @@ -3609,9 +3635,21 @@ CreateProcessW_Hooked { if (f & (DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS)) mutex_timeout = 0; /* to avoid deadlock in GDB */ + gdb_inferior_noncygwin = !fhandler_termios::path_iscygexec_w (n, c); + if (gdb_inferior_noncygwin) + set_console_mode_to_native (); return CreateProcessW_Orig (n, c, pa, ta, inh, f, e, d, si, pi); } +static BOOL WINAPI +ContinueDebugEvent_Hooked + (DWORD p, DWORD t, DWORD s) +{ + if (gdb_inferior_noncygwin) + set_console_mode_to_native (); + return ContinueDebugEvent_Orig (p, t, s); +} + void fhandler_console::fixup_after_fork_exec (bool execing) { @@ -3631,6 +3669,7 @@ fhandler_console::fixup_after_fork_exec (bool execing) /* CreateProcess() is hooked for GDB etc. */ DO_HOOK (NULL, CreateProcessA); DO_HOOK (NULL, CreateProcessW); + DO_HOOK (NULL, ContinueDebugEvent); } // #define WINSTA_ACCESS (WINSTA_READATTRIBUTES | STANDARD_RIGHTS_READ | STANDARD_RIGHTS_WRITE | WINSTA_CREATEDESKTOP | WINSTA_EXITWINDOWS) diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc index d80b5304a4..a35cee0451 100644 --- a/winsup/cygwin/fhandler_tty.cc +++ b/winsup/cygwin/fhandler_tty.cc @@ -157,6 +157,66 @@ set_switch_to_pcon (HANDLE *in, HANDLE *out, HANDLE *err, bool iscygwin) *err = replace_err->get_output_handle_nat (); } +static bool +path_iscygexec_a_w (LPCSTR na, LPSTR ca, LPCWSTR nw, LPWSTR cw) +{ + path_conv path; + tmp_pathbuf tp; + char *prog =tp.c_get (); + if (na) + { + __small_sprintf (prog, "%s", na); + find_exec (prog, path); + } + else if (nw) + { + __small_sprintf (prog, "%W", nw); + find_exec (prog, path); + } + else + { + if (ca) + __small_sprintf (prog, "%s", ca); + else if (cw) + __small_sprintf (prog, "%W", cw); + else + return true; + char *p = prog; + char *p1; + do + if ((p1 = strchr (p, ' ')) || (p1 = p + strlen (p))) + { + p = p1; + if (*p == ' ') + { + *p = '\0'; + find_exec (prog, path); + *p = ' '; + p ++; + } + else if (*p == '\0') + find_exec (prog, path); + } + while (!path.exists() && *p); + } + const char *argv[] = {"", NULL}; /* Dummy */ + av av1; + av1.setup ("", path, "", 1, argv, false); + return path.iscygexec (); +} + +bool +fhandler_termios::path_iscygexec_a (LPCSTR n, LPSTR c) +{ + return path_iscygexec_a_w (n, c, NULL, NULL); +} + +bool +fhandler_termios::path_iscygexec_w (LPCWSTR n, LPWSTR c) +{ + return path_iscygexec_a_w (NULL, NULL, n, c); +} + static bool atexit_func_registered = false; static bool debug_process = false; @@ -220,37 +280,9 @@ CreateProcessA_Hooked siov->hStdOutput = GetStdHandle (STD_OUTPUT_HANDLE); siov->hStdError = GetStdHandle (STD_ERROR_HANDLE); } - path_conv path; - tmp_pathbuf tp; - char *prog =tp.c_get (); - if (n) - __small_sprintf (prog, "%s", n); - else - { - __small_sprintf (prog, "%s", c); - char *p = prog; - char *p1; - do - if ((p1 = strchr (p, ' ')) || (p1 = p + strlen (p))) - { - p = p1; - if (*p == ' ') - { - *p = '\0'; - find_exec (prog, path); - *p = ' '; - p ++; - } - else if (*p == '\0') - find_exec (prog, path); - } - while (!path.exists() && *p); - } - const char *argv[] = {"", NULL}; /* Dummy */ - av av1; - av1.setup ("", path, "", 1, argv, false); + bool path_iscygexec = fhandler_termios::path_iscygexec_a (n, c); set_switch_to_pcon (&siov->hStdInput, &siov->hStdOutput, &siov->hStdError, - path.iscygexec ()); + path_iscygexec); BOOL ret = CreateProcessA_Orig (n, c, pa, ta, inh, f, e, d, siov, pi); h_gdb_process = pi->hProcess; DuplicateHandle (GetCurrentProcess (), h_gdb_process, @@ -259,7 +291,7 @@ CreateProcessA_Hooked debug_process = !!(f & (DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS)); if (debug_process) mutex_timeout = 0; /* to avoid deadlock in GDB */ - if (!atexit_func_registered && !path.iscygexec ()) + if (!atexit_func_registered && !path_iscygexec) { atexit (atexit_func); atexit_func_registered = true; @@ -286,37 +318,9 @@ CreateProcessW_Hooked siov->hStdOutput = GetStdHandle (STD_OUTPUT_HANDLE); siov->hStdError = GetStdHandle (STD_ERROR_HANDLE); } - path_conv path; - tmp_pathbuf tp; - char *prog =tp.c_get (); - if (n) - __small_sprintf (prog, "%W", n); - else - { - __small_sprintf (prog, "%W", c); - char *p = prog; - char *p1; - do - if ((p1 = strchr (p, ' ')) || (p1 = p + strlen (p))) - { - p = p1; - if (*p == ' ') - { - *p = '\0'; - find_exec (prog, path); - *p = ' '; - p ++; - } - else if (*p == '\0') - find_exec (prog, path); - } - while (!path.exists() && *p); - } - const char *argv[] = {"", NULL}; /* Dummy */ - av av1; - av1.setup ("", path, "", 1, argv, false); + bool path_iscygexec = fhandler_termios::path_iscygexec_w (n, c); set_switch_to_pcon (&siov->hStdInput, &siov->hStdOutput, &siov->hStdError, - path.iscygexec ()); + path_iscygexec); BOOL ret = CreateProcessW_Orig (n, c, pa, ta, inh, f, e, d, siov, pi); h_gdb_process = pi->hProcess; DuplicateHandle (GetCurrentProcess (), h_gdb_process, @@ -325,7 +329,7 @@ CreateProcessW_Hooked debug_process = !!(f & (DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS)); if (debug_process) mutex_timeout = 0; /* to avoid deadlock in GDB */ - if (!atexit_func_registered && !path.iscygexec ()) + if (!atexit_func_registered && !path_iscygexec) { atexit (atexit_func); atexit_func_registered = true; From 2256476a14cb45c594013d33934ed1ac83240f50 Mon Sep 17 00:00:00 2001 From: Takashi Yano Date: Sun, 13 Feb 2022 17:11:02 +0900 Subject: [PATCH 9/9] Cygwin: console: Set console mode even if stdin/stdout is redirected. - When non-cygwin app is started in console, console mode is set to tty::native. However, if stdin is redirected, current code does not set the input mode of the console. In this case, if the app opens "CONIN$", the console mode will not be appropriate for non-cygwin app. This patch fixes the issue. Addresses: https://github.com/GitCredentialManager/git-credential-manager/issues/576 --- winsup/cygwin/spawn.cc | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/winsup/cygwin/spawn.cc b/winsup/cygwin/spawn.cc index d7ee5fea79..434a4a0231 100644 --- a/winsup/cygwin/spawn.cc +++ b/winsup/cygwin/spawn.cc @@ -657,23 +657,18 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv, } else if (fh && fh->get_major () == DEV_CONS_MAJOR) { - fhandler_console *cons = (fhandler_console *) fh; - if (!iscygwin ()) + if (!iscygwin () && cons_native == NULL) { - if (cons_native == NULL) - { - cons_native = cons; - cons_ti = &((tty *)cons->tc ())->ti; - cons_owner = cons->get_owner (); - } + fhandler_console *cons = (fhandler_console *) fh; + cons_native = cons; + cons_ti = &((tty *)cons->tc ())->ti; + cons_owner = cons->get_owner (); tty::cons_mode conmode = (ctty_pgid && ctty_pgid == myself->pgid) ? tty::native : tty::restore; - if (fd == 0) - fhandler_console::set_input_mode (conmode, + fhandler_console::set_input_mode (conmode, cons_ti, cons->get_handle_set ()); - else if (fd == 1 || fd == 2) - fhandler_console::set_output_mode (conmode, + fhandler_console::set_output_mode (conmode, cons_ti, cons->get_handle_set ()); } }