44// file that was distributed with this source code.
55
66use crate :: header:: Header ;
7- use crate :: picker:: { get_cgroup , get_command} ;
7+ use crate :: picker:: get_command;
88use crate :: platform:: get_numa_nodes;
99use crate :: tui:: stat:: { CpuValueMode , TuiStat } ;
1010use crate :: Filter :: { EUser , User } ;
@@ -26,6 +26,14 @@ pub(crate) enum InputEvent {
2626 FilterEUser ,
2727 WidthIncrement ,
2828 Delay ,
29+ #[ cfg( target_os = "linux" ) ]
30+ ReniceProc ,
31+ #[ cfg( target_os = "linux" ) ]
32+ ReniceValue ,
33+ #[ cfg( unix) ]
34+ KillProc ,
35+ #[ cfg( unix) ]
36+ KillSignal ,
2937}
3038
3139macro_rules! char {
@@ -98,6 +106,7 @@ pub fn handle_input(
98106 data. write ( ) . unwrap ( ) . 1 = ProcList :: new ( settings, & tui_stat. read ( ) . unwrap ( ) ) ;
99107 should_update. store ( true , Ordering :: Relaxed ) ;
100108 }
109+ #[ cfg( target_os = "linux" ) ]
101110 Event :: Key ( KeyEvent {
102111 code : KeyCode :: Char ( 'g' ) ,
103112 modifiers : KeyModifiers :: CONTROL ,
@@ -121,7 +130,7 @@ pub fn handle_input(
121130 pid,
122131 get_command( pid, false )
123132 ) ;
124- let content = get_cgroup ( pid) ;
133+ let content = crate :: picker :: get_cgroup ( pid) ;
125134 data. 2 = Some ( InfoBar { title, content } ) ;
126135 }
127136 should_update. store ( true , Ordering :: Relaxed ) ;
@@ -164,6 +173,25 @@ pub fn handle_input(
164173 }
165174 should_update. store ( true , Ordering :: Relaxed ) ;
166175 }
176+ #[ cfg( unix) ]
177+ char !( 'k' ) => {
178+ let data = data. read ( ) . unwrap ( ) ;
179+ let mut tui_stat = tui_stat. write ( ) . unwrap ( ) ;
180+ let mut nth = tui_stat. list_offset ;
181+ if data. 1 . collected . is_empty ( ) {
182+ return false ;
183+ }
184+ if data. 1 . collected . len ( ) <= nth {
185+ nth = data. 1 . collected . len ( ) - 1 ;
186+ }
187+ let pid = data. 1 . collected [ nth] . 0 ;
188+ tui_stat. input_value . clear ( ) ;
189+ tui_stat. input_label = format ! ( "PID to signal/kill [default pid = {}]" , pid) ;
190+ tui_stat. selected_process = Some ( pid) ;
191+ tui_stat. input_mode = InputMode :: Input ( InputEvent :: KillProc ) ;
192+
193+ should_update. store ( true , Ordering :: Relaxed ) ;
194+ }
167195 char !( 'l' ) => {
168196 let mut stat = tui_stat. write ( ) . unwrap ( ) ;
169197 stat. show_load_avg = !stat. show_load_avg ;
@@ -194,11 +222,59 @@ pub fn handle_input(
194222 data. write ( ) . unwrap ( ) . 1 = ProcList :: new ( settings, & tui_stat. read ( ) . unwrap ( ) ) ;
195223 should_update. store ( true , Ordering :: Relaxed ) ;
196224 }
225+ #[ cfg( target_os = "linux" ) ]
226+ char !( 'r' ) => {
227+ let data = data. read ( ) . unwrap ( ) ;
228+ let mut tui_stat = tui_stat. write ( ) . unwrap ( ) ;
229+ let mut nth = tui_stat. list_offset ;
230+ if data. 1 . collected . is_empty ( ) {
231+ return false ;
232+ }
233+ if data. 1 . collected . len ( ) <= nth {
234+ nth = data. 1 . collected . len ( ) - 1 ;
235+ }
236+ let pid = data. 1 . collected [ nth] . 0 ;
237+ tui_stat. input_value . clear ( ) ;
238+ tui_stat. input_label = format ! ( "PID to renice [default pid = {}]" , pid) ;
239+ tui_stat. selected_process = Some ( pid) ;
240+ tui_stat. input_mode = InputMode :: Input ( InputEvent :: ReniceProc ) ;
241+
242+ should_update. store ( true , Ordering :: Relaxed ) ;
243+ }
197244 char !( 't' ) => {
198245 let mut stat = tui_stat. write ( ) . unwrap ( ) ;
199246 stat. cpu_graph_mode = stat. cpu_graph_mode . next ( ) ;
200247 should_update. store ( true , Ordering :: Relaxed ) ;
201248 }
249+ #[ cfg( target_os = "linux" ) ]
250+ Event :: Key ( KeyEvent {
251+ code : KeyCode :: Char ( 'u' ) ,
252+ modifiers : KeyModifiers :: CONTROL ,
253+ ..
254+ } ) => {
255+ let mut data = data. write ( ) . unwrap ( ) ;
256+ if data. 2 . is_some ( ) {
257+ data. 2 = None ;
258+ } else {
259+ let tui_stat = tui_stat. read ( ) . unwrap ( ) ;
260+ let mut nth = tui_stat. list_offset ;
261+ if data. 1 . collected . is_empty ( ) {
262+ return false ;
263+ }
264+ if data. 1 . collected . len ( ) <= nth {
265+ nth = data. 1 . collected . len ( ) - 1 ;
266+ }
267+ let pid = data. 1 . collected [ nth] . 0 ;
268+ let title = format ! (
269+ "supplementary groups for pid {}, {}" ,
270+ pid,
271+ get_command( pid, false )
272+ ) ;
273+ let content = crate :: picker:: get_supplementary_groups ( pid) ;
274+ data. 2 = Some ( InfoBar { title, content } ) ;
275+ }
276+ should_update. store ( true , Ordering :: Relaxed ) ;
277+ }
202278 char !( 'U' ) => {
203279 let mut stat = tui_stat. write ( ) . unwrap ( ) ;
204280 stat. input_label = "Which user (blank for all) " . into ( ) ;
@@ -509,5 +585,97 @@ fn handle_input_value(
509585 stat. reset_input ( ) ;
510586 should_update. store ( true , Ordering :: Relaxed ) ;
511587 }
588+ #[ cfg( target_os = "linux" ) ]
589+ InputEvent :: ReniceProc => {
590+ let input_value = { tui_stat. read ( ) . unwrap ( ) . input_value . parse :: < u32 > ( ) } ;
591+ let mut stat = tui_stat. write ( ) . unwrap ( ) ;
592+ if let Ok ( pid) = input_value {
593+ stat. selected_process = Some ( pid) ;
594+ } else {
595+ let is_empty = stat. input_value . trim ( ) . is_empty ( ) ;
596+ stat. reset_input ( ) ;
597+ if !is_empty {
598+ stat. input_message = Some ( " Unacceptable integer " . into ( ) ) ;
599+ should_update. store ( true , Ordering :: Relaxed ) ;
600+ return ;
601+ }
602+ } ;
603+ stat. input_value . clear ( ) ;
604+ stat. input_label = format ! ( "Renice pid {} to value" , stat. selected_process. unwrap( ) ) ;
605+ stat. input_mode = InputMode :: Input ( InputEvent :: ReniceValue ) ;
606+ should_update. store ( true , Ordering :: Relaxed ) ;
607+ }
608+ #[ cfg( target_os = "linux" ) ]
609+ InputEvent :: ReniceValue => {
610+ let mut stat = tui_stat. write ( ) . unwrap ( ) ;
611+ let input_value = stat. input_value . parse :: < i32 > ( ) ;
612+ stat. input_mode = InputMode :: Command ;
613+ stat. reset_input ( ) ;
614+ if input_value. is_err ( ) || input_value. as_ref ( ) . is_ok_and ( |v| * v < -20 || * v > 19 ) {
615+ let is_empty = { tui_stat. read ( ) . unwrap ( ) . input_value . trim ( ) . is_empty ( ) } ;
616+ let mut stat = tui_stat. write ( ) . unwrap ( ) ;
617+ if !is_empty {
618+ stat. input_message = Some ( " Unacceptable nice value " . into ( ) ) ;
619+ }
620+ should_update. store ( true , Ordering :: Relaxed ) ;
621+ return ;
622+ }
623+ let input_value = input_value. unwrap ( ) ;
624+ let pid = stat. selected_process . unwrap ( ) ;
625+ if let Err ( e) = crate :: action:: renice ( pid, input_value) {
626+ stat. input_message = Some ( format ! (
627+ " Failed renice of PID {} to {}: {} " ,
628+ pid, input_value, e
629+ ) ) ;
630+ }
631+ should_update. store ( true , Ordering :: Relaxed ) ;
632+ }
633+ #[ cfg( unix) ]
634+ InputEvent :: KillProc => {
635+ let input_value = { tui_stat. read ( ) . unwrap ( ) . input_value . parse :: < u32 > ( ) } ;
636+ let mut stat = tui_stat. write ( ) . unwrap ( ) ;
637+ if let Ok ( pid) = input_value {
638+ stat. selected_process = Some ( pid) ;
639+ } else {
640+ let is_empty = stat. input_value . trim ( ) . is_empty ( ) ;
641+ stat. reset_input ( ) ;
642+ if !is_empty {
643+ stat. input_message = Some ( " Unacceptable integer " . into ( ) ) ;
644+ should_update. store ( true , Ordering :: Relaxed ) ;
645+ return ;
646+ }
647+ } ;
648+ stat. input_value . clear ( ) ;
649+ stat. input_label = format ! (
650+ "Send pid {} signal [15/sigterm]" ,
651+ stat. selected_process. unwrap( )
652+ ) ;
653+ stat. input_mode = InputMode :: Input ( InputEvent :: KillSignal ) ;
654+ should_update. store ( true , Ordering :: Relaxed ) ;
655+ }
656+ #[ cfg( unix) ]
657+ InputEvent :: KillSignal => {
658+ use uucore:: signals:: signal_by_name_or_value;
659+ let mut stat = tui_stat. write ( ) . unwrap ( ) ;
660+ stat. input_mode = InputMode :: Command ;
661+ stat. reset_input ( ) ;
662+ let signal = if stat. input_value . is_empty ( ) {
663+ 15
664+ } else if let Some ( sig) = signal_by_name_or_value ( & stat. input_value ) {
665+ sig
666+ } else {
667+ stat. input_message = Some ( " Unacceptable signal value" . into ( ) ) ;
668+ should_update. store ( true , Ordering :: Relaxed ) ;
669+ return ;
670+ } ;
671+ let pid = stat. selected_process . unwrap ( ) ;
672+ if let Err ( e) = crate :: action:: kill_process ( pid, signal) {
673+ stat. input_message = Some ( format ! (
674+ " Failed signal pid {} with {}: {} " ,
675+ pid, signal, e
676+ ) ) ;
677+ }
678+ should_update. store ( true , Ordering :: Relaxed ) ;
679+ }
512680 }
513681}
0 commit comments