=== Expected behavior: $ time ./timeout -v -s TERM 2 sh -T -c 'sleep 5 & sleep 5; echo ok; date' timeout: time limit reached or received SIGALRM timeout: sending signal TERM(15) to command 'sh' timeout: signaled 3 processes timeout: sending signal CONT(19) to command 'sh' timeout: collected zombie: pid=1134, exit=0, signal=15 timeout: collected zombie: pid=1135, exit=0, signal=15 timeout: child terminated: pid=1133, exit=0, signal=15 real 0m2.088s <-- user 0m0.000s sys 0m0.018s === Strange with SIGINT and SIGQUIT: $ time ./timeout -v -s INT 2 sh -T -c 'sleep 5 & sleep 5; echo ok; date' timeout: time limit reached or received SIGALRM timeout: sending signal INT(2) to command 'sh' timeout: signaled 3 processes timeout: sending signal CONT(19) to command 'sh' timeout: child terminated: pid=989, exit=0, signal=2 <-- blocking here timeout: collected zombie: pid=990, exit=0, signal=0 real 0m5.009s <-- user 0m0.000s sys 0m0.009s === Another example (Ctrl-C cannot kill the command): $ time ./timeout -v -s INT 2 sh -T -c 'sleep 5 & sleep 5; echo ok; date' ^Ctimeout: received terminating signal INT(2) timeout: sending signal INT(2) to command 'sh' timeout: signaled 3 processes timeout: sending signal CONT(19) to command 'sh' timeout: child terminated: pid=1762, exit=0, signal=2 timeout: time limit reached or received SIGALRM timeout: sending signal INT(2) to command 'sh' timeout: signaled 1 processes timeout: sending signal CONT(19) to command 'sh' ^Ctimeout: received terminating signal INT(2) timeout: sending signal INT(2) to command 'sh' timeout: signaled 1 processes timeout: sending signal CONT(19) to command 'sh' ^Ctimeout: received terminating signal INT(2) timeout: sending signal INT(2) to command 'sh' timeout: signaled 1 processes timeout: sending signal CONT(19) to command 'sh' timeout: collected zombie: pid=1763, exit=0, signal=0 real 0m5.011s user 0m0.000s sys 0m0.008s --------------------------------------------------------------------------- Ran 'pstree $(pgrep timeout)' and it showed the background sleep process was reparented to the timeout(1) utility, for example: $ while true; do if pgrep timeout; then date; pstree $(pgrep timeout); fi; sleep 1; done 1398 Tue Mar 11 18:02:09 CST 2025 -+= 01398 aly ./timeout -v -s TERM 3 sh -T -c sleep 5 & sleep 5; echo ok; date \-+- 01399 aly sh -T -c sleep 5 & sleep 5; echo ok; date |--- 01400 aly sleep 5 \--- 01401 aly sleep 5 1398 Tue Mar 11 18:02:10 CST 2025 -+= 01398 aly ./timeout -v -s TERM 3 sh -T -c sleep 5 & sleep 5; echo ok; date \--- 01400 aly sleep 5 1398 Tue Mar 11 18:02:11 CST 2025 -+= 01398 aly ./timeout -v -s TERM 3 sh -T -c sleep 5 & sleep 5; echo ok; date \--- 01400 aly sleep 5 ^C --------------------------------------------------------------------------- My timeout(1) working branch: https://gitweb.dragonflybsd.org/~aly/dragonfly.git/shortlog/refs/heads/posix-timers