From 0548e74cb3227716cf445f27bd64b8c0b4d0f981 Mon Sep 17 00:00:00 2001 From: Rory Dudley Date: Mon, 26 Feb 2024 23:14:13 -0700 Subject: Cleanup recite(), custom errors, fixed forking First off, moved the giant match statements out of recite(), and into macros in src/recite/ps.rs. There still needs to be two, since any verse using the 'couplet' meter will need to redirect its STDOUT. Now the recite() function returns a Result<(), Mishap>, which can be invoked when calling the incant_ functions. Custom errors were added in the form of 'Mishap''s. They are intended to be returned from the incant_ functions, in the event that something goes wrong with the Command::spawn() or Child::wait(). They each take a String, which should be the verb or stanza that was entered by the user. The incant_ functions separate the functionality of each type of meter from the recite() function. They return a Result, where i32 is the exit code of the program that ran, and Mishap is a possible error. Before, the shell was cheating at forking a process to the background. It would actually spawn a thread to wait for that process to finish. Now, the program simply registers a handler for SIGCHLD, and uses libc's waitpid() function to reap the child process, and print some output to the user, indicating that it's finished. --- src/main.rs | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) (limited to 'src/main.rs') diff --git a/src/main.rs b/src/main.rs index 986e006..44f2726 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,5 @@ mod recite; +use libc::{waitpid, WNOHANG}; use recite::path::prefresh; use recite::Poem; use std::io::{self, Write}; @@ -53,11 +54,12 @@ fn repl(path: &Vec<&Path>, prompt: &str) { // Parse a poem let poem = Poem::read(poetry); match poem { - Some(poem) => { - poem.recite(path, &mut bins); - } + Some(poem) => match poem.recite(path, &mut bins) { + Ok(_) => {} + Err(e) => eprintln!("dwvsh: {}", e), + }, None => {} - } + }; } } @@ -87,6 +89,16 @@ fn main() { io::stdout().flush().unwrap(); }) .unwrap(); + + signal_hook::low_level::register(signal_hook::consts::SIGCHLD, move || { + let mut status: i32 = -1; + let pid: i32 = waitpid(-1, &mut status, WNOHANG); + if pid != -1 { + print!("[&] + done {}", pid); + io::stdout().flush().unwrap(); + } + }) + .unwrap(); }; // Begin evaluating commands -- cgit v1.2.3