https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=dfd1ca3a6ec28c925711f2a06298eafa717488e1
commit dfd1ca3a6ec28c925711f2a06298eafa717488e1 Author: Takashi Yano <[email protected]> Date: Tue Mar 10 11:22:08 2026 +0900 Cygwin: signal: Implement fake stop/cont for non-cygwin process Currently, the following command in bash cannot make `cat | cmd` foreground correctly, and also cannot be terminated by Ctrl-C. $ cat |cmd & $ fg $ (Ctrl-C) This is because, bash does not recognize the process `cmd` as stopped by SIGTTIN, and does not send SIGCONT not only to `cmd` but also to `cat`. To solve this problem, this patch implements fake stop/cont for non- cygwin process such as `cmd`. Even with this patch, the process `cmd` does not enter into stopped state because non-cygwin process itself does not handle cygwin signal, but the stub process for `cmd` enters into stopped state instead by SIGTTIN. Signed-off-by: Takashi Yano <[email protected]> Reviewed-by: Corinna Vinschen <[email protected]> (cherry picked from commit f02f97a626aa69433651de7ce7a65f3efc010a77) Diff: --- winsup/cygwin/exceptions.cc | 19 ++++++++++++++++++- winsup/cygwin/spawn.cc | 2 +- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc index f79978f73..b49adc345 100644 --- a/winsup/cygwin/exceptions.cc +++ b/winsup/cygwin/exceptions.cc @@ -1499,6 +1499,23 @@ _cygtls::handle_SIGCONT () InterlockedAnd ((LONG *) &myself->process_state, ~PID_STOPPED); } +inline static bool +is_stop_or_cont (int sig) +{ + switch (sig) + { + case SIGSTOP: + case SIGTSTP: + case SIGTTIN: + case SIGTTOU: + case SIGCONT: + return true; + default: + break; + } + return false; +} + int sigpacket::process () { @@ -1652,7 +1669,7 @@ exit_sig: thissig.sa_flags &= ~SA_ONSTACK; dosig: - if (have_execed) + if (have_execed && (ch_spawn.iscygwin () || !is_stop_or_cont (si.si_signo))) { sigproc_printf ("terminating captive process"); if (::cygheap->ctty) diff --git a/winsup/cygwin/spawn.cc b/winsup/cygwin/spawn.cc index 04e4a4028..81b99e763 100644 --- a/winsup/cygwin/spawn.cc +++ b/winsup/cygwin/spawn.cc @@ -877,7 +877,7 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv, if (term_spawn_worker.need_cleanup ()) { LONG prev_sigExeced = sigExeced; - while (WaitForSingleObject (pi.hProcess, 100) == WAIT_TIMEOUT) + while (cygwait (pi.hProcess, 100) != WAIT_OBJECT_0) /* If child process does not exit in predetermined time period, the process does not seem to be terminated by the signal sigExeced. Therefore, clear sigExeced here. */
