proc_cli/commands/
freeze.rs1#[cfg(unix)]
11use crate::core::{apply_filters, parse_targets, resolve_targets_excluding_self};
12use crate::error::{ProcError, Result};
13#[cfg(unix)]
14use crate::ui::Printer;
15use clap::Args;
16
17#[derive(Args, Debug)]
19pub struct FreezeCommand {
20 #[arg(required = true)]
22 pub target: String,
23
24 #[arg(long, short = 'y')]
26 pub yes: bool,
27
28 #[arg(long)]
30 pub dry_run: bool,
31
32 #[arg(long, short = 'j')]
34 pub json: bool,
35
36 #[arg(long, short = 'v')]
38 pub verbose: bool,
39
40 #[arg(long = "in", short = 'i', num_args = 0..=1, default_missing_value = ".")]
42 pub in_dir: Option<String>,
43
44 #[arg(long = "by", short = 'b')]
46 pub by_name: Option<String>,
47}
48
49impl FreezeCommand {
50 #[cfg(unix)]
52 pub fn execute(&self) -> Result<()> {
53 use nix::sys::signal::Signal;
54
55 let printer = Printer::from_flags(self.json, self.verbose);
56
57 let targets = parse_targets(&self.target);
58 let (mut processes, not_found) = resolve_targets_excluding_self(&targets);
59
60 if !not_found.is_empty() {
61 printer.warning(&format!("Not found: {}", not_found.join(", ")));
62 }
63
64 apply_filters(&mut processes, &self.in_dir, &self.by_name);
66
67 if processes.is_empty() {
68 return Err(ProcError::ProcessNotFound(self.target.clone()));
69 }
70
71 if self.dry_run {
72 printer.print_dry_run("freeze", &processes);
73 return Ok(());
74 }
75
76 if !printer.ask_confirm("freeze", &processes, self.yes)? {
77 return Ok(());
78 }
79
80 let mut succeeded = Vec::new();
81 let mut failed = Vec::new();
82
83 for proc in &processes {
84 match proc.send_signal(Signal::SIGSTOP) {
85 Ok(()) => succeeded.push(proc.clone()),
86 Err(e) => failed.push((proc.clone(), e.to_string())),
87 }
88 }
89
90 printer.print_action_result("freeze", &succeeded, &failed);
91
92 Ok(())
93 }
94
95 #[cfg(not(unix))]
97 pub fn execute(&self) -> Result<()> {
98 Err(ProcError::NotSupported(
99 "freeze (SIGSTOP) is not supported on Windows".to_string(),
100 ))
101 }
102}