From d8c61e758a88713d919cec804c60db98ceef15db Mon Sep 17 00:00:00 2001 From: "Guillem L. Jara" <4lon3ly0@tutanota.com> Date: Mon, 27 Jul 2026 14:09:36 +0200 Subject: [PATCH 1/4] fix(timeout): add `SIGTTIN` and `SIGTTOU` to waiting loop --- src/uucore/src/lib/features/process/unix.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/uucore/src/lib/features/process/unix.rs b/src/uucore/src/lib/features/process/unix.rs index 1169a6ea23..ff9819243b 100644 --- a/src/uucore/src/lib/features/process/unix.rs +++ b/src/uucore/src/lib/features/process/unix.rs @@ -137,6 +137,7 @@ impl ChildExt for Child { } // otherwise waits again } Ok(Some(Signal::SIGTERM)) if ignore_term => {} // waits again + Ok(Some(Signal::SIGTTIN | Signal::SIGTTOU)) => {} // waits again Ok(Some(signal)) => break Ok(TimeoutRet::Interrupted(signal as usize)), Err(e) => break Err(e), } @@ -158,6 +159,8 @@ pub fn timeout_signal_set() -> SigSet { set.add(Signal::SIGUSR1); set.add(Signal::SIGUSR2); set.add(Signal::SIGCHLD); + set.add(Signal::SIGTTIN); + set.add(Signal::SIGTTOU); set } From 0e6817558275ae85293ea7642baac6bbc7527a9a Mon Sep 17 00:00:00 2001 From: "Guillem L. Jara" <4lon3ly0@tutanota.com> Date: Mon, 27 Jul 2026 14:13:19 +0200 Subject: [PATCH 2/4] fix(timeout): add more terminating signals that must be forwaded --- src/uucore/src/lib/features/process/unix.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/uucore/src/lib/features/process/unix.rs b/src/uucore/src/lib/features/process/unix.rs index ff9819243b..4544eb3a92 100644 --- a/src/uucore/src/lib/features/process/unix.rs +++ b/src/uucore/src/lib/features/process/unix.rs @@ -161,6 +161,10 @@ pub fn timeout_signal_set() -> SigSet { set.add(Signal::SIGCHLD); set.add(Signal::SIGTTIN); set.add(Signal::SIGTTOU); + set.add(Signal::SIGXCPU); + set.add(Signal::SIGXFSZ); + set.add(Signal::SIGVTALRM); + set.add(Signal::SIGPROF); set } From 27259a59c076972b3b744729792059b39f2f083c Mon Sep 17 00:00:00 2001 From: "Guillem L. Jara" <4lon3ly0@tutanota.com> Date: Mon, 27 Jul 2026 14:35:24 +0200 Subject: [PATCH 3/4] chore(tests): add test for `SIGTTIN` handling on timeout --- tests/by-util/test_timeout.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/by-util/test_timeout.rs b/tests/by-util/test_timeout.rs index 038e013de7..dbd4d6db67 100644 --- a/tests/by-util/test_timeout.rs +++ b/tests/by-util/test_timeout.rs @@ -443,3 +443,13 @@ fn test_windows_command_cannot_invoke() { .args(&["1", ".\\not_executable.txt"]) .fails_with_code(126); } + +#[test] +#[cfg(unix)] +fn test_nohang_ttin() { + let (ts, bin) = scenario_with_bin(); + ts.cmd("/bin/sh") + .arg("-c") + .arg(format!("trap 'echo' SIGTTIN; {bin:?} 2 /bin/cat")) + .timeout(Duration::from_secs(4)); +} From 5860112ab71ea6e8ea4c071cabed17c88fc72b36 Mon Sep 17 00:00:00 2001 From: "Guillem L. Jara" <4lon3ly0@tutanota.com> Date: Mon, 27 Jul 2026 14:54:00 +0200 Subject: [PATCH 4/4] chore(CI): appease spell checker --- src/uucore/src/lib/features/process/unix.rs | 1 + tests/by-util/test_timeout.rs | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/uucore/src/lib/features/process/unix.rs b/src/uucore/src/lib/features/process/unix.rs index 4544eb3a92..6830d0faf8 100644 --- a/src/uucore/src/lib/features/process/unix.rs +++ b/src/uucore/src/lib/features/process/unix.rs @@ -8,6 +8,7 @@ // spell-checker:ignore pgrep pwait snice getpgrp // spell-checker:ignore sigwait KTIME timeval itimerval setitimer itimer timerid // spell-checker:ignore sigevent sigev sigval itimerspec signo clockid sevp +// spell-checker:ignore SIGXCPU SIGXFSZ SIGVTALRM SIGPROF use libc::{gid_t, pid_t, uid_t}; #[cfg(not(target_os = "redox"))] diff --git a/tests/by-util/test_timeout.rs b/tests/by-util/test_timeout.rs index dbd4d6db67..b15ab7dfeb 100644 --- a/tests/by-util/test_timeout.rs +++ b/tests/by-util/test_timeout.rs @@ -3,7 +3,7 @@ // For the full copyright and license information, please view the LICENSE // file that was distributed with this source code. -// spell-checker:ignore dont SIGBREAK +// spell-checker:ignore dont SIGBREAK SIGTTIN ttin use rstest::rstest; use std::time::Duration; @@ -446,7 +446,7 @@ fn test_windows_command_cannot_invoke() { #[test] #[cfg(unix)] -fn test_nohang_ttin() { +fn test_continue_terminal_job_ctrl_sigs() { let (ts, bin) = scenario_with_bin(); ts.cmd("/bin/sh") .arg("-c")