From bc121420b8f8a92a2df945c720df004aa7adb764 Mon Sep 17 00:00:00 2001 From: Avril Date: Wed, 1 Mar 2023 06:37:53 +0000 Subject: [PATCH] Chenged return type of `spawn_from_sync()` to be an iterator of `Result>` so the caller can decide what to do if the child terminates without an exit code. Also changed to `eyre::Result<>` to report the specific failure and child process" index. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixed logging of `try_seal_file()`"s verbose output being unconditional. Fortune for collect's current commit: Curse − 凶 --- src/exec.rs | 19 ++++++++++++++----- src/main.rs | 4 ++-- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/src/exec.rs b/src/exec.rs index 171b671..e074e62 100644 --- a/src/exec.rs +++ b/src/exec.rs @@ -92,20 +92,29 @@ pub fn spawn_from<'a, F: ?Sized + AsRawFd>(file: &'a F, opt: Options) -> impl In /// Spawn all `-exec/{}` commands and wait for all children to complete. /// /// # Returns -/// An iterator of the result of spawning each child and its exit status. +/// An iterator of the result of spawning each child and its exit status (if one exists) +/// +/// If the child exited via a signal termination, or another method that does not return a status, the iterator's result will be `Ok(None)` #[inline] -pub fn spawn_from_sync<'a, F: ?Sized + AsRawFd>(file: &'a F, opt: Options) -> impl IntoIterator> + 'a +pub fn spawn_from_sync<'a, F: ?Sized + AsRawFd>(file: &'a F, opt: Options) -> impl IntoIterator>> + 'a { - spawn_from(file, opt).into_iter().map(move |child| -> io::Result<_> { + spawn_from(file, opt).into_iter().zip(0..).map(move |(child, idx)| -> eyre::Result<_> { + + let idx = move || idx.to_string().header(""); match child { Ok(mut child) => { - Ok(child.wait()?.code().unwrap_or(-1)) + Ok(child.wait() + .wrap_err("Failed to wait on child") + .with_note(|| "The child may have detached itself") + .with_section(idx)? + .code()) }, Err(err) => { if_trace!(error!("Failed to spawn child: {err}")); Err(err) + .wrap_err("Failed to spawn child") } - } + }.with_section(idx) }) //todo!("Map `spawn_from(...)` and wait for each child to terminate concurrently. Then return an iterator or the return codes or spawning errors for that now terminated child.") } diff --git a/src/main.rs b/src/main.rs index efff9a6..7aae35b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -172,6 +172,7 @@ fn feature_check() -> eyre::Result<()> } #[inline] + #[cfg_attr(feature="logging", instrument(skip_all, fields(fd = ?file.as_raw_fd())))] fn try_seal_size(file: &F) -> eyre::Result<()> { //if cfg!(feature="exec") { @@ -180,8 +181,7 @@ fn try_seal_size(file: &F) -> eyre::Result<()> .with_warning(|| "This may cause consumers of -exec{} to misbehave") { let fd = file.as_raw_fd(); if_trace!{{ - warn!("Failed to seal file descriptor {fd}: {err}"); - eprintln!("\t{err:?}"); + warn!("Failed to seal file descriptor {fd}: {err}\n\t{err:?}"); }} Err(err).wrap_err("Failed to seal file's length") } else {