mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-28 11:37:44 +00:00
Merge pull request #3501 from tertsdiepraam/kill-group-id
`kill`: kill process group with negative id
This commit is contained in:
commit
27ccb3df2a
3 changed files with 23 additions and 18 deletions
3
Cargo.lock
generated
3
Cargo.lock
generated
|
@ -1158,6 +1158,7 @@ dependencies = [
|
|||
"bitflags",
|
||||
"cfg-if 1.0.0",
|
||||
"libc",
|
||||
"memoffset",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2452,7 +2453,7 @@ name = "uu_kill"
|
|||
version = "0.0.13"
|
||||
dependencies = [
|
||||
"clap 3.1.18",
|
||||
"libc",
|
||||
"nix",
|
||||
"uucore",
|
||||
]
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ path = "src/kill.rs"
|
|||
|
||||
[dependencies]
|
||||
clap = { version = "3.1", features = ["wrap_help", "cargo"] }
|
||||
libc = "0.2.126"
|
||||
nix = { version = "0.24.1", features = ["signal"] }
|
||||
uucore = { version=">=0.0.11", package="uucore", path="../../uucore", features=["signals"] }
|
||||
|
||||
[[bin]]
|
||||
|
|
|
@ -5,16 +5,17 @@
|
|||
// * For the full copyright and license information, please view the LICENSE file
|
||||
// * that was distributed with this source code.
|
||||
|
||||
// spell-checker:ignore (ToDO) signalname pids
|
||||
// spell-checker:ignore (ToDO) signalname pids killpg
|
||||
|
||||
#[macro_use]
|
||||
extern crate uucore;
|
||||
|
||||
use clap::{crate_version, Arg, Command};
|
||||
use libc::{c_int, pid_t};
|
||||
use nix::sys::signal::{self, Signal};
|
||||
use nix::unistd::Pid;
|
||||
use std::io::Error;
|
||||
use uucore::display::Quotable;
|
||||
use uucore::error::{UResult, USimpleError};
|
||||
use uucore::error::{FromIo, UError, UResult, USimpleError};
|
||||
use uucore::signals::{signal_by_name_or_value, ALL_SIGNALS};
|
||||
use uucore::{format_usage, InvalidEncodingHandling};
|
||||
|
||||
|
@ -22,10 +23,9 @@ static ABOUT: &str = "Send signal to processes or list information about signals
|
|||
const USAGE: &str = "{} [OPTIONS]... PID...";
|
||||
|
||||
pub mod options {
|
||||
pub static PIDS_OR_SIGNALS: &str = "pids_of_signals";
|
||||
pub static PIDS_OR_SIGNALS: &str = "pids_or_signals";
|
||||
pub static LIST: &str = "list";
|
||||
pub static TABLE: &str = "table";
|
||||
pub static TABLE_OLD: &str = "table_old";
|
||||
pub static SIGNAL: &str = "signal";
|
||||
}
|
||||
|
||||
|
@ -45,7 +45,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
|||
|
||||
let matches = uu_app().get_matches_from(args);
|
||||
|
||||
let mode = if matches.is_present(options::TABLE) || matches.is_present(options::TABLE_OLD) {
|
||||
let mode = if matches.is_present(options::TABLE) {
|
||||
Mode::Table
|
||||
} else if matches.is_present(options::LIST) {
|
||||
Mode::List
|
||||
|
@ -67,8 +67,12 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
|||
} else {
|
||||
15_usize //SIGTERM
|
||||
};
|
||||
let sig: Signal = (sig as i32)
|
||||
.try_into()
|
||||
.map_err(|e| std::io::Error::from_raw_os_error(e as i32))?;
|
||||
let pids = parse_pids(&pids_or_signals)?;
|
||||
kill(sig, &pids)
|
||||
kill(sig, &pids);
|
||||
Ok(())
|
||||
}
|
||||
Mode::Table => {
|
||||
table();
|
||||
|
@ -84,21 +88,21 @@ pub fn uu_app<'a>() -> Command<'a> {
|
|||
.about(ABOUT)
|
||||
.override_usage(format_usage(USAGE))
|
||||
.infer_long_args(true)
|
||||
.allow_negative_numbers(true)
|
||||
.arg(
|
||||
Arg::new(options::LIST)
|
||||
.short('l')
|
||||
.long(options::LIST)
|
||||
.help("Lists signals")
|
||||
.conflicts_with(options::TABLE)
|
||||
.conflicts_with(options::TABLE_OLD),
|
||||
.conflicts_with(options::TABLE),
|
||||
)
|
||||
.arg(
|
||||
Arg::new(options::TABLE)
|
||||
.short('t')
|
||||
.short_alias('L')
|
||||
.long(options::TABLE)
|
||||
.help("Lists table of signals"),
|
||||
)
|
||||
.arg(Arg::new(options::TABLE_OLD).short('L').hide(true))
|
||||
.arg(
|
||||
Arg::new(options::SIGNAL)
|
||||
.short('s')
|
||||
|
@ -190,21 +194,21 @@ fn parse_signal_value(signal_name: &str) -> UResult<usize> {
|
|||
}
|
||||
}
|
||||
|
||||
fn parse_pids(pids: &[String]) -> UResult<Vec<usize>> {
|
||||
fn parse_pids(pids: &[String]) -> UResult<Vec<i32>> {
|
||||
pids.iter()
|
||||
.map(|x| {
|
||||
x.parse::<usize>().map_err(|e| {
|
||||
x.parse::<i32>().map_err(|e| {
|
||||
USimpleError::new(1, format!("failed to parse argument {}: {}", x.quote(), e))
|
||||
})
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn kill(signal_value: usize, pids: &[usize]) -> UResult<()> {
|
||||
fn kill(sig: Signal, pids: &[i32]) {
|
||||
for &pid in pids {
|
||||
if unsafe { libc::kill(pid as pid_t, signal_value as c_int) } != 0 {
|
||||
show!(USimpleError::new(1, format!("{}", Error::last_os_error())));
|
||||
if let Err(e) = signal::kill(Pid::from_raw(pid), sig) {
|
||||
show!(Error::from_raw_os_error(e as i32)
|
||||
.map_err_context(|| format!("sending signal to {} failed", pid)));
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue