Return child in result.

This commit is contained in:
shy 2021-04-16 12:46:02 +02:00
parent d3f609976a
commit f1c6eedb21
2 changed files with 24 additions and 21 deletions

View file

@ -29,8 +29,7 @@ pub use consts::ui::*;
pub fn run( pub fn run(
config: Config, config: Config,
mut alarm_roster: AlarmRoster, mut alarm_roster: AlarmRoster,
spawned: &mut Option<process::Child>, ) -> Result<Option<process::Child>, std::io::Error>
) -> Result<(), std::io::Error>
{ {
let mut layout = Layout::new(); let mut layout = Layout::new();
// Initialise roster_width. // Initialise roster_width.
@ -43,6 +42,7 @@ pub fn run(
let mut input_keys = async_stdin.keys(); let mut input_keys = async_stdin.keys();
let stdout = std::io::stdout(); let stdout = std::io::stdout();
let mut stdout = stdout.lock().into_raw_mode()?; let mut stdout = stdout.lock().into_raw_mode()?;
let mut child: Option<process::Child> = None;
let mut force_redraw = true; let mut force_redraw = true;
// Register signals. // Register signals.
@ -121,21 +121,21 @@ pub fn run(
// Check on last spawned child process prior to processing the // Check on last spawned child process prior to processing the
// alarm roster and possibly starting a new one. // alarm roster and possibly starting a new one.
if let Some(ref mut child) = spawned { if let Some(ref mut spawn) = child {
match child.try_wait() { match spawn.try_wait() {
// Process exited successfully. // Process exited successfully.
Ok(Some(status)) if status.success() => *spawned = None, Ok(Some(status)) if status.success() => child = None,
// Abnormal exit. // Abnormal exit.
Ok(Some(status)) => { Ok(Some(status)) => {
eprintln!("Spawned process terminated with non-zero exit status. ({})", status); eprintln!("Spawned process terminated with non-zero exit status. ({})", status);
*spawned = None; child = None;
}, },
// Process is still running. // Process is still running.
Ok(None) => (), Ok(None) => (),
// Other error. // Other error.
Err(error) => { Err(error) => {
eprintln!("Error executing command. ({})", error); eprintln!("Error executing command. ({})", error);
*spawned = None; child = None;
}, },
} }
} }
@ -156,8 +156,8 @@ pub fn run(
match config.command { match config.command {
// Run command if configured and no command is running. // Run command if configured and no command is running.
Some(ref command) if spawned.is_none() => { Some(ref command) if child.is_none() => {
*spawned = exec_command(command, alarm.time, &alarm.label); child = exec_command(command, alarm.time, &alarm.label);
}, },
// Last command is still running. // Last command is still running.
Some(_) => eprintln!("Not executing command, as its predecessor is still running"), Some(_) => eprintln!("Not executing command, as its predecessor is still running"),
@ -345,7 +345,7 @@ pub fn run(
cursor::Show)?; cursor::Show)?;
stdout.flush()?; stdout.flush()?;
Ok(()) Ok(child)
} }
pub struct Config { pub struct Config {

View file

@ -12,7 +12,7 @@ fn main() {
process::exit(1); process::exit(1);
}); });
// Read alarm times from stdin if stdin not a tty. // Read alarm times from stdin if stdin is not a tty.
let stdin = std::io::stdin(); let stdin = std::io::stdin();
if !termion::is_tty(&stdin) { if !termion::is_tty(&stdin) {
stdin.lock(); stdin.lock();
@ -22,20 +22,23 @@ fn main() {
} }
} }
// Holds spawned child process if any. // Run main loop. Returns spawned child process if any.
let mut spawned: Option<process::Child> = None; let child = match run(config, alarm_roster) {
Ok(child) => child,
Err(error) => {
eprintln!("Main loop exited with error: {}", error);
process::exit(1);
},
};
// Run main loop. // Wait for remaining spawned process to exit.
if let Err(e) = run(config, alarm_roster, &mut spawned) { if let Some(mut child) = child {
eprintln!("Main loop exited with error: {}", e);
process::exit(1);
}
// Wait for remaining spawned processes to exit.
if let Some(ref mut child) = spawned {
eprint!("Waiting for spawned process (PID {}) to finish ...", child.id()); eprint!("Waiting for spawned process (PID {}) to finish ...", child.id());
match child.wait() { match child.wait() {
Ok(status) if status.success() => eprintln!(" ok"),
// Unix only.
Ok(status) if status.code().is_none() => eprintln!(" interrupted ({})", status),
Ok(status) => eprintln!(" ok ({})", status), Ok(status) => eprintln!(" ok ({})", status),
Err(error) => eprintln!(" failed ({})", error), Err(error) => eprintln!(" failed ({})", error),
} }