Skip to content

Commit 43c6b07

Browse files
committed
refactor(kill): remove unsafe libc::kill, use safe rustix process APIs
Replace the single unsafe libc::kill() call with safe rustix equivalents: kill_process, kill_process_group, kill_current_process_group, and their test_kill_* variants for signal 0.
1 parent 07d6f27 commit 43c6b07

3 files changed

Lines changed: 37 additions & 5 deletions

File tree

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/uu/kill/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ uucore = { workspace = true, features = ["signals"] }
2424
fluent = { workspace = true }
2525

2626
[target.'cfg(unix)'.dependencies]
27-
nix = { workspace = true, features = ["signal"] }
27+
rustix = { workspace = true, features = ["process"] }
2828

2929
[[bin]]
3030
name = "kill"

src/uu/kill/src/kill.rs

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -250,11 +250,43 @@ fn parse_pids(pids: &[String]) -> UResult<Vec<i32>> {
250250
.collect()
251251
}
252252

253-
fn kill(sig: Option<Signal>, pids: &[i32]) {
253+
fn kill(sig: i32, pids: &[i32]) {
254+
use rustix::process::{
255+
Pid, Signal, kill_current_process_group, kill_process, kill_process_group,
256+
test_kill_current_process_group, test_kill_process, test_kill_process_group,
257+
};
258+
254259
for &pid in pids {
255-
if let Err(e) = signal::kill(Pid::from_raw(pid), sig) {
260+
let esrch = || Err(rustix::io::Errno::SRCH);
261+
let result = if sig == 0 {
262+
// Signal 0: test if process/group exists
263+
match pid.cmp(&0) {
264+
std::cmp::Ordering::Greater => {
265+
Pid::from_raw(pid).map_or_else(esrch, test_kill_process)
266+
}
267+
std::cmp::Ordering::Equal => test_kill_current_process_group(),
268+
std::cmp::Ordering::Less => {
269+
Pid::from_raw(-pid).map_or_else(esrch, test_kill_process_group)
270+
}
271+
}
272+
} else {
273+
// SAFETY: sig is a non-zero value from user input; the kernel
274+
// will reject truly invalid signal numbers with EINVAL.
275+
let signal = unsafe { Signal::from_raw_unchecked(sig) };
276+
match pid.cmp(&0) {
277+
std::cmp::Ordering::Greater => {
278+
Pid::from_raw(pid).map_or_else(esrch, |p| kill_process(p, signal))
279+
}
280+
std::cmp::Ordering::Equal => kill_current_process_group(signal),
281+
std::cmp::Ordering::Less => {
282+
Pid::from_raw(-pid).map_or_else(esrch, |p| kill_process_group(p, signal))
283+
}
284+
}
285+
};
286+
287+
if let Err(e) = result {
256288
show!(
257-
Error::from_raw_os_error(e as i32)
289+
Error::from(e)
258290
.map_err_context(|| { translate!("kill-error-sending-signal", "pid" => pid) })
259291
);
260292
}

0 commit comments

Comments
 (0)