Skip to content

Commit 713b996

Browse files
committed
top: tui impl k (kill)
1 parent 80718ee commit 713b996

File tree

3 files changed

+82
-1
lines changed

3 files changed

+82
-1
lines changed

src/uu/top/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ license.workspace = true
1111
version.workspace = true
1212

1313
[dependencies]
14-
uucore = { workspace = true, features = ["utmpx", "uptime"] }
14+
uucore = { workspace = true, features = ["utmpx", "uptime", "signals"] }
1515
clap = { workspace = true }
1616
crossterm = { workspace = true }
1717
libc = { workspace = true }

src/uu/top/src/action.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,16 @@ pub(crate) fn renice(pid: u32, nice_value: i32) -> uucore::error::UResult<()> {
1414
Ok(())
1515
}
1616
}
17+
18+
#[cfg(unix)]
19+
pub(crate) fn kill_process(pid: u32, sig: usize) -> uucore::error::UResult<()> {
20+
use nix::sys::signal;
21+
use nix::sys::signal::Signal;
22+
use nix::unistd::Pid;
23+
use uucore::error::USimpleError;
24+
let result = signal::kill(Pid::from_raw(pid as i32), Signal::try_from(sig as i32)?);
25+
match result {
26+
Ok(_) => Ok(()),
27+
Err(_) => Err(USimpleError::new(0, "Permission Denied")),
28+
}
29+
}

src/uu/top/src/tui/input.rs

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ pub(crate) enum InputEvent {
3030
ReniceProc,
3131
#[cfg(target_os = "linux")]
3232
ReniceValue,
33+
KillProc,
34+
KillSignal,
3335
}
3436

3537
macro_rules! char {
@@ -169,6 +171,25 @@ pub fn handle_input(
169171
}
170172
should_update.store(true, Ordering::Relaxed);
171173
}
174+
#[cfg(unix)]
175+
char!('k') => {
176+
let data = data.read().unwrap();
177+
let mut tui_stat = tui_stat.write().unwrap();
178+
let mut nth = tui_stat.list_offset;
179+
if data.1.collected.is_empty() {
180+
return false;
181+
}
182+
if data.1.collected.len() <= nth {
183+
nth = data.1.collected.len() - 1;
184+
}
185+
let pid = data.1.collected[nth].0;
186+
tui_stat.input_value.clear();
187+
tui_stat.input_label = format!("PID to signal/kill [default pid = {}]", pid);
188+
tui_stat.selected_process = Some(pid);
189+
tui_stat.input_mode = InputMode::Input(InputEvent::KillProc);
190+
191+
should_update.store(true, Ordering::Relaxed);
192+
}
172193
char!('l') => {
173194
let mut stat = tui_stat.write().unwrap();
174195
stat.show_load_avg = !stat.show_load_avg;
@@ -607,5 +628,52 @@ fn handle_input_value(
607628
}
608629
should_update.store(true, Ordering::Relaxed);
609630
}
631+
#[cfg(unix)]
632+
InputEvent::KillProc => {
633+
let input_value = { tui_stat.read().unwrap().input_value.parse::<u32>() };
634+
let mut stat = tui_stat.write().unwrap();
635+
if let Ok(pid) = input_value {
636+
stat.selected_process = Some(pid);
637+
} else {
638+
let is_empty = stat.input_value.trim().is_empty();
639+
stat.reset_input();
640+
if !is_empty {
641+
stat.input_message = Some(" Unacceptable integer ".into());
642+
should_update.store(true, Ordering::Relaxed);
643+
return;
644+
}
645+
};
646+
stat.input_value.clear();
647+
stat.input_label = format!(
648+
"Send pid {} signal [15/sigterm]",
649+
stat.selected_process.unwrap()
650+
);
651+
stat.input_mode = InputMode::Input(InputEvent::KillSignal);
652+
should_update.store(true, Ordering::Relaxed);
653+
}
654+
#[cfg(unix)]
655+
InputEvent::KillSignal => {
656+
use uucore::signals::signal_by_name_or_value;
657+
let mut stat = tui_stat.write().unwrap();
658+
stat.input_mode = InputMode::Command;
659+
stat.reset_input();
660+
let signal = if stat.input_value.is_empty() {
661+
15
662+
} else if let Some(sig) = signal_by_name_or_value(&stat.input_value) {
663+
sig
664+
} else {
665+
stat.input_message = Some(" Unacceptable signal value".into());
666+
should_update.store(true, Ordering::Relaxed);
667+
return;
668+
};
669+
let pid = stat.selected_process.unwrap();
670+
if let Err(e) = crate::action::kill_process(pid, signal) {
671+
stat.input_message = Some(format!(
672+
" Failed signal pid {} with {}: {} ",
673+
pid, signal, e
674+
));
675+
}
676+
should_update.store(true, Ordering::Relaxed);
677+
}
610678
}
611679
}

0 commit comments

Comments
 (0)