[newlib-cygwin] Cygwin: signal: Implement fake stop/cont for non-cygwin process
Takashi Yano
tyan0@sourceware.org
Thu Mar 12 11:33:19 GMT 2026
https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=f02f97a626aa69433651de7ce7a65f3efc010a77
commit f02f97a626aa69433651de7ce7a65f3efc010a77
Author: Takashi Yano <takashi.yano@nifty.ne.jp>
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 <takashi.yano@nifty.ne.jp>
Reviewed-by: Corinna Vinschen <corinna@vinschen.de>
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 830846431..158d8675b 100644
--- a/winsup/cygwin/exceptions.cc
+++ b/winsup/cygwin/exceptions.cc
@@ -1508,6 +1508,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 ()
{
@@ -1661,7 +1678,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 65f208435..8f976b9a0 100644
--- a/winsup/cygwin/spawn.cc
+++ b/winsup/cygwin/spawn.cc
@@ -861,7 +861,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. */
More information about the Cygwin-cvs
mailing list