diff --git a/src/cli.rs b/src/cli.rs index b525653..128a3ea 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -74,6 +74,8 @@ pub struct Args { /// Interval for polling. (seconds) #[builder(default = "2")] pub poll_interval: u32, + #[builder(default)] + pub watch_idle: bool, } impl ArgsBuilder { @@ -205,7 +207,11 @@ where .help("Do not wrap command in 'sh -c' resp. 'cmd.exe /C'") .short("n") .long("no-shell")) - .arg(Arg::with_name("once").short("1").hidden(true)); + .arg(Arg::with_name("once").short("1").hidden(true)) + .arg(Arg::with_name("watch-idle") + .help("Ignores commands while the process is still running") + .short("W") + .long("watch-idle")); let args = match from { None => app.get_matches(), @@ -300,5 +306,6 @@ where once: args.is_present("once"), poll: args.occurrences_of("poll") > 0, poll_interval, + watch_idle: args.is_present("watch-idle"), }) } diff --git a/src/run.rs b/src/run.rs index 4e17d11..a281792 100644 --- a/src/run.rs +++ b/src/run.rs @@ -189,6 +189,19 @@ impl ExecHandler { Ok(()) } + + pub fn has_running_process(&self) -> bool { + let guard = self + .child_process + .read() + .expect("poisoned lock in signal_process"); + + if let Some(ref _child) = *guard { + return true; + } + + false + } } impl Handler for ExecHandler { @@ -217,20 +230,35 @@ impl Handler for ExecHandler { // let scenario = (self.args.restart, self.signal.is_some()); + let running_process = self.has_running_process(); + match scenario { // Custom restart behaviour (--restart was given, and --signal specified): // Send specified signal to the child, wait for it to exit, then run the command again (true, true) => { - signal_process(&self.child_process, self.signal, true); - self.spawn(ops)?; + if self.args.watch_idle { + if !running_process { + self.spawn(ops)?; + } + } else { + signal_process(&self.child_process, self.signal, true); + self.spawn(ops)?; + } } // Default restart behaviour (--restart was given, but --signal wasn't specified): // Send SIGTERM to the child, wait for it to exit, then run the command again (true, false) => { let sigterm = signal::new(Some("SIGTERM".into())); - signal_process(&self.child_process, sigterm, true); - self.spawn(ops)?; + + if self.args.watch_idle { + if !running_process { + self.spawn(ops)?; + } + } else { + signal_process(&self.child_process, sigterm, true); + self.spawn(ops)?; + } } // SIGHUP scenario: --signal was given, but --restart was not @@ -240,8 +268,14 @@ impl Handler for ExecHandler { // Default behaviour (neither --signal nor --restart specified): // Make sure the previous run was ended, then run the command again (false, false) => { - signal_process(&self.child_process, None, true); - self.spawn(ops)?; + if self.args.watch_idle { + if !running_process { + self.spawn(ops)?; + } + } else { + signal_process(&self.child_process, None, true); + self.spawn(ops)?; + } } }