From 5f0cdafad8c85f0aef0fb97aa5515e68815b1f78 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/7] 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 c2e2dde9f03..d88be19fef8 100644 --- a/src/uucore/src/lib/features/process/unix.rs +++ b/src/uucore/src/lib/features/process/unix.rs @@ -84,6 +84,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), } @@ -107,6 +108,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 da084878c989de34a089b944ea641958c5536709 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/7] 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 d88be19fef8..d4f4b47f0a0 100644 --- a/src/uucore/src/lib/features/process/unix.rs +++ b/src/uucore/src/lib/features/process/unix.rs @@ -110,6 +110,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 940e32706d01cf1bc4441121d01707ac9ef9eb95 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/7] 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 3d09a6e21ac..ae8e0cafd80 100644 --- a/tests/by-util/test_timeout.rs +++ b/tests/by-util/test_timeout.rs @@ -555,3 +555,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 83cdc110acc40ec87f304ff13cd8f09f8d4614a1 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/7] 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 d4f4b47f0a0..d7e96e84f93 100644 --- a/src/uucore/src/lib/features/process/unix.rs +++ b/src/uucore/src/lib/features/process/unix.rs @@ -5,6 +5,7 @@ // 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 #[cfg(not(any(target_os = "fuchsia", target_os = "haiku")))] use libc::pid_t; diff --git a/tests/by-util/test_timeout.rs b/tests/by-util/test_timeout.rs index ae8e0cafd80..a1f92e5e448 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; @@ -558,7 +558,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") From f67508433a397966a0c0fe7e3c7ca2885eea5167 Mon Sep 17 00:00:00 2001 From: "Guillem L. Jara" <4lon3ly0@tutanota.com> Date: Thu, 30 Jul 2026 20:46:16 +0200 Subject: [PATCH 5/7] chore(tests): fix ctrl sig test case --- tests/by-util/test_timeout.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/by-util/test_timeout.rs b/tests/by-util/test_timeout.rs index a1f92e5e448..34001aef4a6 100644 --- a/tests/by-util/test_timeout.rs +++ b/tests/by-util/test_timeout.rs @@ -559,9 +559,10 @@ fn test_windows_command_cannot_invoke() { #[test] #[cfg(unix)] fn test_continue_terminal_job_ctrl_sigs() { + let name = util_name!(); let (ts, bin) = scenario_with_bin(); ts.cmd("/bin/sh") .arg("-c") - .arg(format!("trap 'echo' SIGTTIN; {bin:?} 2 /bin/cat")) + .arg(format!("trap 'echo' SIGTTIN; {bin:?} {name} 2 /bin/cat")) .timeout(Duration::from_secs(4)); } From 4b8e56aa8016daac9258b8a5f124a47d1a4ea944 Mon Sep 17 00:00:00 2001 From: "Guillem L. Jara" <4lon3ly0@tutanota.com> Date: Sun, 25 Oct 2026 14:29:10 +0100 Subject: [PATCH 6/7] fix(timeout): also ignore `SIGTSTP` --- src/uucore/src/lib/features/process/unix.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/uucore/src/lib/features/process/unix.rs b/src/uucore/src/lib/features/process/unix.rs index d7e96e84f93..da433fb60ae 100644 --- a/src/uucore/src/lib/features/process/unix.rs +++ b/src/uucore/src/lib/features/process/unix.rs @@ -85,7 +85,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::SIGTTIN | Signal::SIGTTOU | Signal::SIGTSTP)) => {} // waits again Ok(Some(signal)) => break Ok(TimeoutRet::Interrupted(signal as usize)), Err(e) => break Err(e), } @@ -111,6 +111,7 @@ pub fn timeout_signal_set() -> SigSet { set.add(Signal::SIGCHLD); set.add(Signal::SIGTTIN); set.add(Signal::SIGTTOU); + set.add(Signal::SIGTSTP); set.add(Signal::SIGXCPU); set.add(Signal::SIGXFSZ); set.add(Signal::SIGVTALRM); From cefdd786f526b5d92e233e984d40695755423e2a Mon Sep 17 00:00:00 2001 From: "Guillem L. Jara" <4lon3ly0@tutanota.com> Date: Sun, 25 Oct 2026 15:53:02 +0100 Subject: [PATCH 7/7] chore(timeout): enforce test success --- tests/by-util/test_timeout.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/by-util/test_timeout.rs b/tests/by-util/test_timeout.rs index 34001aef4a6..41e0acec715 100644 --- a/tests/by-util/test_timeout.rs +++ b/tests/by-util/test_timeout.rs @@ -564,5 +564,6 @@ fn test_continue_terminal_job_ctrl_sigs() { ts.cmd("/bin/sh") .arg("-c") .arg(format!("trap 'echo' SIGTTIN; {bin:?} {name} 2 /bin/cat")) - .timeout(Duration::from_secs(4)); + .timeout(Duration::from_secs(4)) + .succeeds(); }