mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-30 12:37:49 +00:00
Merge pull request #349 from Arcterus/kill-short-sigs
kill: implement short signals (fixes #242) and bug fixes
This commit is contained in:
commit
7b7e5c8543
2 changed files with 40 additions and 10 deletions
45
kill/kill.rs
45
kill/kill.rs
|
@ -52,7 +52,6 @@ pub enum Mode {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn uumain(args: Vec<String>) -> int {
|
pub fn uumain(args: Vec<String>) -> int {
|
||||||
|
|
||||||
let opts = [
|
let opts = [
|
||||||
optflag("h", "help", "display this help and exit"),
|
optflag("h", "help", "display this help and exit"),
|
||||||
optflag("V", "version", "output version information and exit"),
|
optflag("V", "version", "output version information and exit"),
|
||||||
|
@ -63,6 +62,7 @@ pub fn uumain(args: Vec<String>) -> int {
|
||||||
|
|
||||||
let usage = usage("[options] <pid> [...]", opts);
|
let usage = usage("[options] <pid> [...]", opts);
|
||||||
|
|
||||||
|
let (args, obs_signal) = handle_obsolete(args);
|
||||||
|
|
||||||
let matches = match getopts(args.tail(), opts) {
|
let matches = match getopts(args.tail(), opts) {
|
||||||
Ok(m) => m,
|
Ok(m) => m,
|
||||||
|
@ -72,7 +72,6 @@ pub fn uumain(args: Vec<String>) -> int {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
let mode = if matches.opt_present("version") {
|
let mode = if matches.opt_present("version") {
|
||||||
Version
|
Version
|
||||||
} else if matches.opt_present("help") {
|
} else if matches.opt_present("help") {
|
||||||
|
@ -86,7 +85,7 @@ pub fn uumain(args: Vec<String>) -> int {
|
||||||
};
|
};
|
||||||
|
|
||||||
match mode {
|
match mode {
|
||||||
Kill => kill(matches.opt_str("signal").unwrap_or("9".to_string()).as_slice(), matches.free),
|
Kill => return kill(matches.opt_str("signal").unwrap_or(obs_signal.unwrap_or("9".to_string())).as_slice(), matches.free),
|
||||||
Table => table(),
|
Table => table(),
|
||||||
List => list(matches.opt_str("list")),
|
List => list(matches.opt_str("list")),
|
||||||
Help => help(NAME, usage.as_slice()),
|
Help => help(NAME, usage.as_slice()),
|
||||||
|
@ -100,8 +99,29 @@ fn version() {
|
||||||
println!("{} {}", NAME, VERSION);
|
println!("{} {}", NAME, VERSION);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn table() {
|
fn handle_obsolete(mut args: Vec<String>) -> (Vec<String>, Option<String>) {
|
||||||
|
let mut i = 0;
|
||||||
|
while i < args.len() {
|
||||||
|
// this is safe because slice is valid when it is referenced
|
||||||
|
let slice: &str = unsafe { std::mem::transmute(args.get(i).as_slice()) };
|
||||||
|
if slice.char_at(0) == '-' && slice.len() > 1 && slice.char_at(1).is_digit() {
|
||||||
|
let val = slice.slice_from(1);
|
||||||
|
match from_str(val) {
|
||||||
|
Some(num) => {
|
||||||
|
if signals::is_signal(num) {
|
||||||
|
args.remove(i);
|
||||||
|
return (args, Some(val.to_string()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None => break /* getopts will error out for us */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
(args, None)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn table() {
|
||||||
let mut name_width = 0;
|
let mut name_width = 0;
|
||||||
/* Compute the maximum width of a signal name. */
|
/* Compute the maximum width of a signal name. */
|
||||||
for s in ALL_SIGNALS.iter() {
|
for s in ALL_SIGNALS.iter() {
|
||||||
|
@ -113,7 +133,7 @@ fn table() {
|
||||||
for (idx, signal) in ALL_SIGNALS.iter().enumerate() {
|
for (idx, signal) in ALL_SIGNALS.iter().enumerate() {
|
||||||
print!("{0: >#2} {1: <#8}", idx+1, signal.name);
|
print!("{0: >#2} {1: <#8}", idx+1, signal.name);
|
||||||
//TODO: obtain max signal width here
|
//TODO: obtain max signal width here
|
||||||
|
|
||||||
if (idx+1) % 7 == 0 {
|
if (idx+1) % 7 == 0 {
|
||||||
println!("");
|
println!("");
|
||||||
}
|
}
|
||||||
|
@ -144,7 +164,7 @@ fn print_signals() {
|
||||||
} else {
|
} else {
|
||||||
pos += 1;
|
pos += 1;
|
||||||
print!(" ");
|
print!(" ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -176,7 +196,8 @@ fn signal_by_name_or_value(signal_name_or_value: &str) -> Option<uint> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
fn kill(signalname: &str, pids: std::vec::Vec<String>) {
|
fn kill(signalname: &str, pids: std::vec::Vec<String>) -> int {
|
||||||
|
let mut status = 0;
|
||||||
let optional_signal_value = signal_by_name_or_value(signalname);
|
let optional_signal_value = 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,
|
||||||
|
@ -187,11 +208,15 @@ fn kill(signalname: &str, pids: std::vec::Vec<String>) {
|
||||||
Some(x) => {
|
Some(x) => {
|
||||||
let result = Process::kill(x, signal_value as int);
|
let result = Process::kill(x, signal_value as int);
|
||||||
match result {
|
match result {
|
||||||
Ok(_) => (),
|
Ok(_) => (),
|
||||||
Err(_) => ()
|
Err(f) => {
|
||||||
|
show_error!("{}", f);
|
||||||
|
status = 1;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
None => crash!(EXIT_ERR, "failed to parse argument {}", signalname)
|
None => crash!(EXIT_ERR, "failed to parse argument {}", pid)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
status
|
||||||
}
|
}
|
||||||
|
|
|
@ -138,3 +138,8 @@ pub static ALL_SIGNALS:[Signal<'static>, ..31] = [
|
||||||
Signal{ name: "USR1", value:30 },
|
Signal{ name: "USR1", value:30 },
|
||||||
Signal{ name: "USR2", value:31 },
|
Signal{ name: "USR2", value:31 },
|
||||||
];
|
];
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn is_signal(num: uint) -> bool {
|
||||||
|
num < ALL_SIGNALS.len()
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue