timeout: support --verbose

This commit is contained in:
Michael Debertol 2021-06-10 18:34:05 +02:00
parent b0b937dc3e
commit 8e0ed2d20e
2 changed files with 37 additions and 1 deletions

View file

@ -17,7 +17,7 @@ use std::io::ErrorKind;
use std::process::{Command, Stdio};
use std::time::Duration;
use uucore::process::ChildExt;
use uucore::signals::signal_by_name_or_value;
use uucore::signals::{signal_by_name_or_value, signal_name_by_value};
use uucore::InvalidEncodingHandling;
static ABOUT: &str = "Start COMMAND, and kill it if still running after DURATION.";
@ -33,6 +33,7 @@ pub mod options {
pub static KILL_AFTER: &str = "kill-after";
pub static SIGNAL: &str = "signal";
pub static PRESERVE_STATUS: &str = "preserve-status";
pub static VERBOSE: &str = "verbose";
// Positional args.
pub static DURATION: &str = "duration";
@ -45,6 +46,7 @@ struct Config {
signal: usize,
duration: Duration,
preserve_status: bool,
verbose: bool,
command: Vec<String>,
}
@ -74,6 +76,7 @@ impl Config {
let preserve_status: bool = options.is_present(options::PRESERVE_STATUS);
let foreground = options.is_present(options::FOREGROUND);
let verbose = options.is_present(options::VERBOSE);
let command = options
.values_of(options::COMMAND)
@ -88,6 +91,7 @@ impl Config {
duration,
preserve_status,
command,
verbose,
}
}
}
@ -124,6 +128,12 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
.help("specify the signal to be sent on timeout; SIGNAL may be a name like 'HUP' or a number; see 'kill -l' for a list of signals")
.takes_value(true)
)
.arg(
Arg::with_name(options::VERBOSE)
.short("v")
.long(options::VERBOSE)
.help("diagnose to stderr any signal sent upon timeout")
)
.arg(
Arg::with_name(options::DURATION)
.index(1)
@ -147,6 +157,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
config.kill_after,
config.foreground,
config.preserve_status,
config.verbose,
)
}
@ -159,6 +170,7 @@ fn timeout(
kill_after: Duration,
foreground: bool,
preserve_status: bool,
verbose: bool,
) -> i32 {
if !foreground {
unsafe { libc::setpgid(0, 0) };
@ -185,6 +197,13 @@ fn timeout(
match process.wait_or_timeout(duration) {
Ok(Some(status)) => status.code().unwrap_or_else(|| status.signal().unwrap()),
Ok(None) => {
if verbose {
show_error!(
"sending signal {} to command '{}'",
signal_name_by_value(signal).unwrap(),
cmd[0]
);
}
return_if_err!(ERR_EXIT_STATUS, process.send_signal(signal));
match process.wait_or_timeout(kill_after) {
Ok(Some(status)) => {
@ -199,6 +218,9 @@ fn timeout(
// XXX: this may not be right
return 124;
}
if verbose {
show_error!("sending signal KILL to command '{}'", cmd[0]);
}
return_if_err!(
ERR_EXIT_STATUS,
process

View file

@ -17,3 +17,17 @@ fn test_command_with_args() {
.succeeds()
.stdout_only("abcd");
}
#[test]
fn test_verbose() {
for &verbose_flag in &["-v", "--verbose"] {
new_ucmd!()
.args(&[verbose_flag, ".1", "sleep", "10"])
.fails()
.stderr_only("timeout: sending signal TERM to command 'sleep'");
new_ucmd!()
.args(&[verbose_flag, "-s0", "-k.1", ".1", "sleep", "10"])
.fails()
.stderr_only("timeout: sending signal EXIT to command 'sleep'\ntimeout: sending signal KILL to command 'sleep'");
}
}