1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-27 19:17:43 +00:00

kill: migrate to clap

Fixes #2122.
This commit is contained in:
Nicolas Thery 2021-05-01 15:51:12 +02:00
parent 0ff1058998
commit 1dccbfd21e
3 changed files with 65 additions and 26 deletions

1
Cargo.lock generated
View file

@ -2041,6 +2041,7 @@ dependencies = [
name = "uu_kill" name = "uu_kill"
version = "0.0.6" version = "0.0.6"
dependencies = [ dependencies = [
"clap",
"libc", "libc",
"uucore", "uucore",
"uucore_procs", "uucore_procs",

View file

@ -15,6 +15,7 @@ edition = "2018"
path = "src/kill.rs" path = "src/kill.rs"
[dependencies] [dependencies]
clap = "2.33"
libc = "0.2.42" libc = "0.2.42"
uucore = { version=">=0.0.8", package="uucore", path="../../uucore", features=["signals"] } uucore = { version=">=0.0.8", package="uucore", path="../../uucore", features=["signals"] }
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }

View file

@ -10,18 +10,26 @@
#[macro_use] #[macro_use]
extern crate uucore; extern crate uucore;
use clap::{App, Arg};
use libc::{c_int, pid_t}; use libc::{c_int, pid_t};
use std::io::Error; use std::io::Error;
use uucore::signals::ALL_SIGNALS; use uucore::signals::ALL_SIGNALS;
use uucore::InvalidEncodingHandling; use uucore::InvalidEncodingHandling;
static SYNTAX: &str = "[options] <pid> [...]"; static VERSION: &str = env!("CARGO_PKG_VERSION");
static SUMMARY: &str = ""; static ABOUT: &str = "Send signal to processes or list information about signals.";
static LONG_HELP: &str = "";
static EXIT_OK: i32 = 0; static EXIT_OK: i32 = 0;
static EXIT_ERR: i32 = 1; static EXIT_ERR: i32 = 1;
pub mod options {
pub static PIDS_OR_SIGNALS: &str = "pids_of_signals";
pub static LIST: &str = "list";
pub static TABLE: &str = "table";
pub static TABLE_OLD: &str = "table_old";
pub static SIGNAL: &str = "signal";
}
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
pub enum Mode { pub enum Mode {
Kill, Kill,
@ -33,41 +41,70 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
let args = args let args = args
.collect_str(InvalidEncodingHandling::Ignore) .collect_str(InvalidEncodingHandling::Ignore)
.accept_any(); .accept_any();
let (args, obs_signal) = handle_obsolete(args); let (args, obs_signal) = handle_obsolete(args);
let matches = app!(SYNTAX, SUMMARY, LONG_HELP)
.optopt("s", "signal", "specify the <signal> to be sent", "SIGNAL")
.optflagopt(
"l",
"list",
"list all signal names, or convert one to a name",
"LIST",
)
.optflag("L", "table", "list all signal names in a nice table")
.parse(args);
let mode = if matches.opt_present("table") { let usage = format!("{} [OPTIONS]... PID...", executable!());
let matches = App::new(executable!())
.version(VERSION)
.about(ABOUT)
.usage(&usage[..])
.arg(
Arg::with_name(options::LIST)
.short("l")
.long(options::LIST)
.help("Lists signals")
.conflicts_with(options::TABLE)
.conflicts_with(options::TABLE_OLD),
)
.arg(
Arg::with_name(options::TABLE)
.short("t")
.long(options::TABLE)
.help("Lists table of signals"),
)
.arg(Arg::with_name(options::TABLE_OLD).short("L").hidden(true))
.arg(
Arg::with_name(options::SIGNAL)
.short("s")
.long(options::SIGNAL)
.help("Sends given signal")
.takes_value(true),
)
.arg(
Arg::with_name(options::PIDS_OR_SIGNALS)
.hidden(true)
.multiple(true),
)
.get_matches_from(args);
let mode = if matches.is_present(options::TABLE) || matches.is_present(options::TABLE_OLD) {
Mode::Table Mode::Table
} else if matches.opt_present("list") { } else if matches.is_present(options::LIST) {
Mode::List Mode::List
} else { } else {
Mode::Kill Mode::Kill
}; };
let pids_or_signals: Vec<String> = matches
.values_of(options::PIDS_OR_SIGNALS)
.map(|v| v.map(ToString::to_string).collect())
.unwrap_or_default();
match mode { match mode {
Mode::Kill => { Mode::Kill => {
return kill( let sig = match (obs_signal, matches.value_of(options::SIGNAL)) {
&matches (Some(s), Some(_)) => s, // -s takes precedence
.opt_str("signal") (Some(s), None) => s,
.unwrap_or_else(|| obs_signal.unwrap_or_else(|| "TERM".to_owned())), (None, Some(s)) => s.to_owned(),
matches.free, (None, None) => "TERM".to_owned(),
) };
return kill(&sig, &pids_or_signals);
} }
Mode::Table => table(), Mode::Table => table(),
Mode::List => list(matches.opt_str("list")), Mode::List => list(pids_or_signals.get(0).cloned()),
} }
0 EXIT_OK
} }
fn handle_obsolete(mut args: Vec<String>) -> (Vec<String>, Option<String>) { fn handle_obsolete(mut args: Vec<String>) -> (Vec<String>, Option<String>) {
@ -148,14 +185,14 @@ fn list(arg: Option<String>) {
}; };
} }
fn kill(signalname: &str, pids: std::vec::Vec<String>) -> i32 { fn kill(signalname: &str, pids: &[String]) -> i32 {
let mut status = 0; let mut status = 0;
let optional_signal_value = uucore::signals::signal_by_name_or_value(signalname); let optional_signal_value = uucore::signals::signal_by_name_or_value(signalname);
let signal_value = match optional_signal_value { let signal_value = match optional_signal_value {
Some(x) => x, Some(x) => x,
None => crash!(EXIT_ERR, "unknown signal name {}", signalname), None => crash!(EXIT_ERR, "unknown signal name {}", signalname),
}; };
for pid in &pids { for pid in pids {
match pid.parse::<usize>() { match pid.parse::<usize>() {
Ok(x) => { Ok(x) => {
if unsafe { libc::kill(x as pid_t, signal_value as c_int) } != 0 { if unsafe { libc::kill(x as pid_t, signal_value as c_int) } != 0 {