Skip to main content

strat9_kernel/shell/commands/util/
watch.rs

1use super::*;
2
3/// Execute a command repeatedly at a given interval.
4///
5/// Usage: `watch <seconds> <command...>`
6///
7/// Runs the specified command every N seconds until Ctrl+C.
8pub fn cmd_watch(args: &[String]) -> Result<(), ShellError> {
9    if args.len() < 2 {
10        shell_println!("Usage: watch <seconds> <command...>");
11        return Err(ShellError::InvalidArguments);
12    }
13    let interval_secs: u64 = args[0].parse().map_err(|_| {
14        shell_println!("watch: invalid interval '{}'", args[0]);
15        ShellError::InvalidArguments
16    })?;
17    if interval_secs == 0 {
18        shell_println!("watch: interval must be >= 1 second");
19        return Err(ShellError::InvalidArguments);
20    }
21    let cmd_line = args[1..].join(" ");
22    let hz = crate::arch::x86_64::timer::TIMER_HZ;
23    let interval_ticks = interval_secs * hz;
24
25    shell_println!("Every {}s: {}", interval_secs, cmd_line);
26    shell_println!("Press Ctrl+C to stop.\n");
27
28    loop {
29        if crate::shell::is_interrupted() {
30            break;
31        }
32        if let Some(ch) = crate::arch::x86_64::keyboard::read_char() {
33            if ch == 0x03 || ch == b'q' {
34                break;
35            }
36        }
37
38        crate::shell::run_line(&cmd_line);
39
40        let start = crate::process::scheduler::ticks();
41        while crate::process::scheduler::ticks() - start < interval_ticks {
42            if crate::shell::is_interrupted() {
43                return Ok(());
44            }
45            if let Some(ch) = crate::arch::x86_64::keyboard::read_char() {
46                if ch == 0x03 || ch == b'q' {
47                    return Ok(());
48                }
49            }
50            crate::process::yield_task();
51        }
52    }
53    Ok(())
54}