1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-08-03 06:27:45 +00:00

Update timeout.rs to new io

This commit is contained in:
Remi Rampin 2015-06-30 15:23:55 -04:00
parent 0ed57b3896
commit 66a40d555d

View file

@ -1,5 +1,4 @@
#![crate_name = "timeout"] #![crate_name = "timeout"]
#![feature(collections, core, io, old_io, rustc_private)]
/* /*
* This file is part of the uutils coreutils package. * This file is part of the uutils coreutils package.
@ -13,8 +12,9 @@
extern crate getopts; extern crate getopts;
extern crate libc; extern crate libc;
use std::old_io::{PathDoesntExist, FileNotFound}; use std::io::{ErrorKind, Write};
use std::old_io::process::{Command, ExitStatus, ExitSignal, InheritFd}; use std::process::{Command, Stdio};
use std::os::unix::process::ExitStatusExt;
#[path = "../common/util.rs"] #[path = "../common/util.rs"]
#[macro_use] #[macro_use]
@ -38,15 +38,14 @@ static ERR_EXIT_STATUS: i32 = 125;
pub fn uumain(args: Vec<String>) -> i32 { pub fn uumain(args: Vec<String>) -> i32 {
let program = args[0].clone(); let program = args[0].clone();
let opts = [ let mut opts = getopts::Options::new();
getopts::optflag("", "preserve-status", "exit with the same status as COMMAND, even when the command times out"), opts.optflag("", "preserve-status", "exit with the same status as COMMAND, even when the command times out");
getopts::optflag("", "foreground", "when not running timeout directly from a shell prompt, allow COMMAND to read from the TTY and get TTY signals; in this mode, children of COMMAND will not be timed out"), opts.optflag("", "foreground", "when not running timeout directly from a shell prompt, allow COMMAND to read from the TTY and get TTY signals; in this mode, children of COMMAND will not be timed out");
getopts::optopt("k", "kill-after", "also send a KILL signal if COMMAND is still running this long after the initial signal was sent", "DURATION"), opts.optopt("k", "kill-after", "also send a KILL signal if COMMAND is still running this long after the initial signal was sent", "DURATION");
getopts::optflag("s", "signal", "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"), opts.optflag("s", "signal", "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");
getopts::optflag("h", "help", "display this help and exit"), opts.optflag("h", "help", "display this help and exit");
getopts::optflag("V", "version", "output version information and exit") opts.optflag("V", "version", "output version information and exit");
]; let matches = match opts.parse(&args[1..]) {
let matches = match getopts::getopts(args.tail(), &opts) {
Ok(m) => m, Ok(m) => m,
Err(f) => { Err(f) => {
crash!(ERR_EXIT_STATUS, "{}", f) crash!(ERR_EXIT_STATUS, "{}", f)
@ -58,7 +57,7 @@ pub fn uumain(args: Vec<String>) -> i32 {
Usage: Usage:
{} [OPTION] DURATION COMMAND [ARG]... {} [OPTION] DURATION COMMAND [ARG]...
{}", NAME, VERSION, program, getopts::usage("Start COMMAND, and kill it if still running after DURATION.", &opts)); {}", NAME, VERSION, program, &opts.usage("Start COMMAND, and kill it if still running after DURATION."));
} else if matches.opt_present("version") { } else if matches.opt_present("version") {
println!("{} {}", NAME, VERSION); println!("{} {}", NAME, VERSION);
} else if matches.free.len() < 2 { } else if matches.free.len() < 2 {
@ -69,7 +68,7 @@ Usage:
let status = matches.opt_present("preserve-status"); let status = matches.opt_present("preserve-status");
let foreground = matches.opt_present("foreground"); let foreground = matches.opt_present("foreground");
let kill_after = match matches.opt_str("kill-after") { let kill_after = match matches.opt_str("kill-after") {
Some(tstr) => match time::from_str(tstr.as_slice()) { Some(tstr) => match time::from_str(&tstr) {
Ok(time) => time, Ok(time) => time,
Err(f) => { Err(f) => {
show_error!("{}", f); show_error!("{}", f);
@ -79,7 +78,7 @@ Usage:
None => 0f64 None => 0f64
}; };
let signal = match matches.opt_str("signal") { let signal = match matches.opt_str("signal") {
Some(sigstr) => match signals::signal_by_name_or_value(sigstr.as_slice()) { Some(sigstr) => match signals::signal_by_name_or_value(&sigstr) {
Some(sig) => sig, Some(sig) => sig,
None => { None => {
show_error!("invalid signal '{}'", sigstr); show_error!("invalid signal '{}'", sigstr);
@ -88,14 +87,14 @@ Usage:
}, },
None => signals::signal_by_name_or_value("TERM").unwrap() None => signals::signal_by_name_or_value("TERM").unwrap()
}; };
let duration = match time::from_str(matches.free[0].as_slice()) { let duration = match time::from_str(&matches.free[0]) {
Ok(time) => time, Ok(time) => time,
Err(f) => { Err(f) => {
show_error!("{}", f); show_error!("{}", f);
return ERR_EXIT_STATUS; return ERR_EXIT_STATUS;
} }
}; };
return timeout(matches.free[1].as_slice(), &matches.free[2..], duration, signal, kill_after, foreground, status); return timeout(&matches.free[1], &matches.free[2..], duration, signal, kill_after, foreground, status);
} }
0 0
@ -106,14 +105,14 @@ fn timeout(cmdname: &str, args: &[String], duration: f64, signal: usize, kill_af
unsafe { setpgid(0, 0) }; unsafe { setpgid(0, 0) };
} }
let mut process = match Command::new(cmdname).args(args) let mut process = match Command::new(cmdname).args(args)
.stdin(InheritFd(0)) .stdin(Stdio::inherit())
.stdout(InheritFd(1)) .stdout(Stdio::inherit())
.stderr(InheritFd(2)) .stderr(Stdio::inherit())
.spawn() { .spawn() {
Ok(p) => p, Ok(p) => p,
Err(err) => { Err(err) => {
show_error!("failed to execute process: {}", err); show_error!("failed to execute process: {}", err);
if err.kind == FileNotFound || err.kind == PathDoesntExist { if err.kind() == ErrorKind::NotFound {
// XXX: not sure which to use // XXX: not sure which to use
return 127; return 127;
} else { } else {
@ -124,20 +123,14 @@ fn timeout(cmdname: &str, args: &[String], duration: f64, signal: usize, kill_af
}; };
process.set_timeout(Some((duration * 1000f64) as u64)); // FIXME: this ignores the f64... process.set_timeout(Some((duration * 1000f64) as u64)); // FIXME: this ignores the f64...
match process.wait() { match process.wait() {
Ok(status) => match status { Ok(status) => status.code().unwrap_or_else(|| status.signal().unwrap()),
ExitStatus(stat) => stat as i32,
ExitSignal(stat) => stat as i32
},
Err(_) => { Err(_) => {
return_if_err!(ERR_EXIT_STATUS, process.signal(signal as isize)); return_if_err!(ERR_EXIT_STATUS, process.signal(signal as isize));
process.set_timeout(Some((kill_after * 1000f64) as u64)); process.set_timeout(Some((kill_after * 1000f64) as u64));
match process.wait() { match process.wait() {
Ok(status) => { Ok(status) => {
if preserve_status { if preserve_status {
match status { status.code().unwrap_or_else(|| status.signal().unwrap())
ExitStatus(stat) => stat as i32,
ExitSignal(stat) => stat as i32
}
} else { } else {
124 124
} }