mirror of
https://github.com/uutils/coreutils.git
synced 2026-06-10 15:48:22 -07:00
uucore: support realtime signals (RTMIN/RTMAX) in signal_by_name_or_value
`signal_by_name_or_value()` only looked up signals from the static ALL_SIGNALS array, which doesn't include realtime signals. This caused `timeout -s RTMAX`, `kill -s RTMIN`, and `env --default-signal=RTMAX` to reject valid signal names. Extend the function to fall back to realtime_signal_bounds() for both name lookups and numeric values in the realtime range, matching the behavior already present in signal_list_value_by_name_or_number(). Also fix timeout's report_if_verbose() to use signal_list_name_by_value instead of signal_name_by_value, so verbose output doesn't panic for realtime signal numbers. Fixes GNU test: tests/env/env-signal-handler.sh Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
committed by
Daniel Hofstetter
parent
f6451c7d20
commit
6e18efb218
@@ -185,9 +185,13 @@ LINESIZE
|
||||
NAMESIZE
|
||||
RTLD_NEXT
|
||||
RTLD
|
||||
RTMAX
|
||||
RTMIN
|
||||
SIGABRT
|
||||
SIGINT
|
||||
SIGKILL
|
||||
SIGRTMAX
|
||||
SIGRTMIN
|
||||
SIGSTOP
|
||||
SIGTERM
|
||||
SYS_fdatasync
|
||||
|
||||
@@ -22,7 +22,7 @@ use uucore::translate;
|
||||
|
||||
use uucore::{
|
||||
format_usage,
|
||||
signals::{signal_by_name_or_value, signal_name_by_value},
|
||||
signals::{signal_by_name_or_value, signal_list_name_by_value},
|
||||
};
|
||||
|
||||
use nix::sys::signal::{SigHandler, Signal, kill};
|
||||
@@ -227,7 +227,7 @@ fn report_if_verbose(signal: usize, cmd: &str, verbose: bool) {
|
||||
let s = if signal == 0 {
|
||||
"0".to_string()
|
||||
} else {
|
||||
signal_name_by_value(signal).unwrap().to_string()
|
||||
signal_list_name_by_value(signal).unwrap()
|
||||
};
|
||||
let mut stderr = std::io::stderr();
|
||||
let _ = writeln!(
|
||||
|
||||
@@ -396,11 +396,24 @@ pub static ALL_SIGNALS: [&str; 32] = [
|
||||
pub fn signal_by_name_or_value(signal_name_or_value: &str) -> Option<usize> {
|
||||
let signal_name_upcase = signal_name_or_value.to_uppercase();
|
||||
if let Ok(value) = signal_name_upcase.parse() {
|
||||
return if is_signal(value) { Some(value) } else { None };
|
||||
if is_signal(value) {
|
||||
return Some(value);
|
||||
}
|
||||
return realtime_signal_bounds()
|
||||
.filter(|&(rtmin, rtmax)| value >= rtmin && value <= rtmax)
|
||||
.map(|_| value);
|
||||
}
|
||||
let signal_name = signal_name_upcase.trim_start_matches("SIG");
|
||||
|
||||
ALL_SIGNALS.iter().position(|&s| s == signal_name)
|
||||
if let Some(pos) = ALL_SIGNALS.iter().position(|&s| s == signal_name) {
|
||||
return Some(pos);
|
||||
}
|
||||
|
||||
realtime_signal_bounds().and_then(|(rtmin, rtmax)| match signal_name {
|
||||
"RTMIN" => Some(rtmin),
|
||||
"RTMAX" => Some(rtmax),
|
||||
_ => None,
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns true if the given number is a valid signal number.
|
||||
@@ -754,3 +767,19 @@ fn linux_unnamed_signal_numbers_are_valid_for_lists() {
|
||||
assert_eq!(signal_list_value_by_name_or_number("32"), Some(32));
|
||||
assert_eq!(signal_list_value_by_name_or_number("33"), Some(33));
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||
#[test]
|
||||
fn linux_realtime_signals_resolve_by_name_or_value() {
|
||||
let (rtmin, rtmax) = realtime_signal_bounds().unwrap();
|
||||
|
||||
// By name
|
||||
assert_eq!(signal_by_name_or_value("RTMIN"), Some(rtmin));
|
||||
assert_eq!(signal_by_name_or_value("RTMAX"), Some(rtmax));
|
||||
assert_eq!(signal_by_name_or_value("SIGRTMIN"), Some(rtmin));
|
||||
assert_eq!(signal_by_name_or_value("SIGRTMAX"), Some(rtmax));
|
||||
|
||||
// By numeric value
|
||||
assert_eq!(signal_by_name_or_value(&rtmin.to_string()), Some(rtmin));
|
||||
assert_eq!(signal_by_name_or_value(&rtmax.to_string()), Some(rtmax));
|
||||
}
|
||||
|
||||
@@ -286,3 +286,21 @@ fn test_foreground_signal0_kill_after() {
|
||||
.args(&["--foreground", "-s0", "-k.1", ".1", "sleep", "10"])
|
||||
.fails_with_code(137);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||
fn test_realtime_signal_names() {
|
||||
// timeout should accept RTMIN and RTMAX as valid signal names
|
||||
new_ucmd!()
|
||||
.args(&["-v", "-s", "RTMAX", ".1", "sleep", "1"])
|
||||
.fails()
|
||||
.stderr_contains("sending signal RTMAX to command");
|
||||
new_ucmd!()
|
||||
.args(&["-v", "-s", "RTMIN", ".1", "sleep", "1"])
|
||||
.fails()
|
||||
.stderr_contains("sending signal RTMIN to command");
|
||||
new_ucmd!()
|
||||
.args(&["-v", "-s", "SIGRTMAX", ".1", "sleep", "1"])
|
||||
.fails()
|
||||
.stderr_contains("sending signal RTMAX to command");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user