Skip to content

Commit 6ff7d1b

Browse files
committed
top: tui impl r (renice)
1 parent 3aeeb2c commit 6ff7d1b

File tree

4 files changed

+87
-0
lines changed

4 files changed

+87
-0
lines changed

src/uu/top/src/action.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// This file is part of the uutils procps package.
2+
//
3+
// For the full copyright and license information, please view the LICENSE
4+
// file that was distributed with this source code.
5+
6+
#[cfg(target_os = "linux")]
7+
pub(crate) fn renice(pid: u32, nice_value: i32) -> uucore::error::UResult<()> {
8+
use libc::{setpriority, PRIO_PROCESS};
9+
use uucore::error::USimpleError;
10+
let result = unsafe { setpriority(PRIO_PROCESS, pid, nice_value) };
11+
if result == -1 {
12+
Err(USimpleError::new(0, "Permission Denied"))
13+
} else {
14+
Ok(())
15+
}
16+
}

src/uu/top/src/top.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ use uucore::{
2424
const ABOUT: &str = help_about!("top.md");
2525
const USAGE: &str = help_usage!("top.md");
2626

27+
mod action;
2728
mod field;
2829
mod header;
2930
mod picker;

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

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ pub(crate) enum InputEvent {
2626
FilterEUser,
2727
WidthIncrement,
2828
Delay,
29+
#[cfg(target_os = "linux")]
30+
ReniceProc,
31+
#[cfg(target_os = "linux")]
32+
ReniceValue,
2933
}
3034

3135
macro_rules! char {
@@ -195,6 +199,25 @@ pub fn handle_input(
195199
data.write().unwrap().1 = ProcList::new(settings, &tui_stat.read().unwrap());
196200
should_update.store(true, Ordering::Relaxed);
197201
}
202+
#[cfg(target_os = "linux")]
203+
char!('r') => {
204+
let data = data.read().unwrap();
205+
let mut tui_stat = tui_stat.write().unwrap();
206+
let mut nth = tui_stat.list_offset;
207+
if data.1.collected.is_empty() {
208+
return false;
209+
}
210+
if data.1.collected.len() <= nth {
211+
nth = data.1.collected.len() - 1;
212+
}
213+
let pid = data.1.collected[nth].0;
214+
tui_stat.input_value.clear();
215+
tui_stat.input_label = format!("PID to renice [default pid = {}]", pid);
216+
tui_stat.selected_process = Some(pid);
217+
tui_stat.input_mode = InputMode::Input(InputEvent::ReniceProc);
218+
219+
should_update.store(true, Ordering::Relaxed);
220+
}
198221
char!('t') => {
199222
let mut stat = tui_stat.write().unwrap();
200223
stat.cpu_graph_mode = stat.cpu_graph_mode.next();
@@ -539,5 +562,50 @@ fn handle_input_value(
539562
stat.reset_input();
540563
should_update.store(true, Ordering::Relaxed);
541564
}
565+
#[cfg(target_os = "linux")]
566+
InputEvent::ReniceProc => {
567+
let input_value = { tui_stat.read().unwrap().input_value.parse::<u32>() };
568+
let mut stat = tui_stat.write().unwrap();
569+
if let Ok(pid) = input_value {
570+
stat.selected_process = Some(pid);
571+
} else {
572+
let is_empty = stat.input_value.trim().is_empty();
573+
stat.reset_input();
574+
if !is_empty {
575+
stat.input_message = Some(" Unacceptable integer ".into());
576+
should_update.store(true, Ordering::Relaxed);
577+
return;
578+
}
579+
};
580+
stat.input_value.clear();
581+
stat.input_label = format!("Renice pid {} to value", stat.selected_process.unwrap());
582+
stat.input_mode = InputMode::Input(InputEvent::ReniceValue);
583+
should_update.store(true, Ordering::Relaxed);
584+
}
585+
#[cfg(target_os = "linux")]
586+
InputEvent::ReniceValue => {
587+
let mut stat = tui_stat.write().unwrap();
588+
let input_value = stat.input_value.parse::<i32>();
589+
stat.input_mode = InputMode::Command;
590+
stat.reset_input();
591+
if input_value.is_err() || input_value.as_ref().is_ok_and(|v| *v < -20 || *v > 19) {
592+
let is_empty = { tui_stat.read().unwrap().input_value.trim().is_empty() };
593+
let mut stat = tui_stat.write().unwrap();
594+
if !is_empty {
595+
stat.input_message = Some(" Unacceptable nice value ".into());
596+
}
597+
should_update.store(true, Ordering::Relaxed);
598+
return;
599+
}
600+
let input_value = input_value.unwrap();
601+
let pid = stat.selected_process.unwrap();
602+
if let Err(e) = crate::action::renice(pid, input_value) {
603+
stat.input_message = Some(format!(
604+
" Failed renice of PID {} to {}: {} ",
605+
pid, input_value, e
606+
));
607+
}
608+
should_update.store(true, Ordering::Relaxed);
609+
}
542610
}
543611
}

src/uu/top/src/tui/stat.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ pub(crate) struct TuiStat {
1212
pub input_label: String,
1313
pub input_value: String,
1414
pub input_message: Option<String>, // Info or error
15+
pub selected_process: Option<u32>,
1516

1617
pub show_load_avg: bool,
1718
pub cpu_graph_mode: CpuGraphMode,
@@ -51,6 +52,7 @@ impl TuiStat {
5152
input_label: String::new(),
5253
input_value: String::new(),
5354
input_message: None,
55+
selected_process: None,
5456

5557
show_load_avg: true,
5658
cpu_graph_mode: CpuGraphMode::default(),

0 commit comments

Comments
 (0)