Tend to spawned processes.
This commit is contained in:
parent
91d3e81eca
commit
5e01fbe066
2 changed files with 52 additions and 10 deletions
18
src/alarm.rs
18
src/alarm.rs
|
@ -1,5 +1,5 @@
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::process::{Command, Stdio};
|
use std::process::{Command, Stdio, Child};
|
||||||
use termion::{color, cursor, style};
|
use termion::{color, cursor, style};
|
||||||
use termion::raw::RawTerminal;
|
use termion::raw::RawTerminal;
|
||||||
use crate::{Clock, Config, Layout, Position};
|
use crate::{Clock, Config, Layout, Position};
|
||||||
|
@ -267,7 +267,7 @@ impl AlarmRoster {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Execute the command given on the command line.
|
// Execute the command given on the command line.
|
||||||
pub fn alarm_exec(config: &Config, elapsed: u32) {
|
pub fn alarm_exec(config: &Config, elapsed: u32) -> Option<Child> {
|
||||||
let mut args: Vec<String> = Vec::new();
|
let mut args: Vec<String> = Vec::new();
|
||||||
let time: String;
|
let time: String;
|
||||||
|
|
||||||
|
@ -283,14 +283,14 @@ pub fn alarm_exec(config: &Config, elapsed: u32) {
|
||||||
args.push(s.replace("{}", &time));
|
args.push(s.replace("{}", &time));
|
||||||
}
|
}
|
||||||
|
|
||||||
if Command::new(&exec[0])
|
match Command::new(&exec[0]).args(&args[1..])
|
||||||
.args(&args[1..])
|
.stdout(Stdio::null()).stdin(Stdio::null()).spawn() {
|
||||||
.stdout(Stdio::null())
|
Ok(child) => return Some(child),
|
||||||
.stdin(Stdio::null())
|
Err(error) => {
|
||||||
.spawn().is_err() {
|
eprintln!("Error: Could not execute command. ({})", error);
|
||||||
|
|
||||||
eprintln!("Error: Could not execute command");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
44
src/main.rs
44
src/main.rs
|
@ -78,6 +78,8 @@ fn main() {
|
||||||
let mut buffer = String::new();
|
let mut buffer = String::new();
|
||||||
let mut buffer_updated: bool = false;
|
let mut buffer_updated: bool = false;
|
||||||
let mut countdown = Countdown::new();
|
let mut countdown = Countdown::new();
|
||||||
|
// Child process of alarm_exec().
|
||||||
|
let mut spawned: Option<std::process::Child> = None;
|
||||||
|
|
||||||
// Initialise roster_width.
|
// Initialise roster_width.
|
||||||
layout.set_roster_width(alarm_roster.width());
|
layout.set_roster_width(alarm_roster.width());
|
||||||
|
@ -254,7 +256,12 @@ fn main() {
|
||||||
|
|
||||||
// Run command if configured.
|
// Run command if configured.
|
||||||
if config.alarm_exec.is_some() {
|
if config.alarm_exec.is_some() {
|
||||||
alarm_exec(&config, clock.elapsed);
|
if spawned.is_none() {
|
||||||
|
spawned = alarm_exec(&config, clock.elapsed);
|
||||||
|
} else {
|
||||||
|
// The last command is still running.
|
||||||
|
eprintln!("Not executing command, as its predecessor is still running");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Quit if configured.
|
// Quit if configured.
|
||||||
if config.auto_quit && !alarm_roster.active() {
|
if config.auto_quit && !alarm_roster.active() {
|
||||||
|
@ -295,6 +302,26 @@ fn main() {
|
||||||
countdown.draw(&mut stdout);
|
countdown.draw(&mut stdout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check any spawned child process.
|
||||||
|
if let Some(ref mut child) = spawned {
|
||||||
|
match child.try_wait() {
|
||||||
|
// Process exited successfully.
|
||||||
|
Ok(Some(status)) if status.success() => spawned = None,
|
||||||
|
// Abnormal exit.
|
||||||
|
Ok(Some(status)) => {
|
||||||
|
eprintln!("Spawned process terminated with non-zero exit status. ({})", status);
|
||||||
|
spawned = None;
|
||||||
|
},
|
||||||
|
// Process is still running.
|
||||||
|
Ok(None) => (),
|
||||||
|
// Other error.
|
||||||
|
Err(error) => {
|
||||||
|
eprintln!("Error executing command. ({})", error);
|
||||||
|
spawned = None;
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Reset redraw_all and flush stdout.
|
// Reset redraw_all and flush stdout.
|
||||||
layout.force_redraw = false;
|
layout.force_redraw = false;
|
||||||
stdout.flush().unwrap();
|
stdout.flush().unwrap();
|
||||||
|
@ -311,6 +338,21 @@ fn main() {
|
||||||
cursor::Goto(1, 1),
|
cursor::Goto(1, 1),
|
||||||
cursor::Show)
|
cursor::Show)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
// Reset terminal.
|
||||||
|
drop(stdout);
|
||||||
|
drop(input_keys);
|
||||||
|
|
||||||
|
// Wait for remaining spawned processes to exit.
|
||||||
|
if let Some(ref mut child) = spawned {
|
||||||
|
print!("Waiting for spawned processes (PID {}) to exit ...", child.id());
|
||||||
|
std::io::stdout().flush().unwrap();
|
||||||
|
|
||||||
|
match child.wait() {
|
||||||
|
Ok(status) => println!(" ok ({})", status),
|
||||||
|
Err(error) => println!(" failed ({})", error),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn usage() {
|
fn usage() {
|
||||||
|
|
Loading…
Reference in a new issue