Chenged return type of `spawn_from_sync()` to be an iterator of `Result<Option<i32>>` 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.

Fixed logging of `try_seal_file()`"s verbose output being unconditional.

Fortune for collect's current commit: Curse − 凶
exec
Avril 2 years ago
parent 79721444ba
commit bc121420b8
Signed by: flanchan
GPG Key ID: 284488987C31F630

@ -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. /// Spawn all `-exec/{}` commands and wait for all children to complete.
/// ///
/// # Returns /// # 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] #[inline]
pub fn spawn_from_sync<'a, F: ?Sized + AsRawFd>(file: &'a F, opt: Options) -> impl IntoIterator<Item = io::Result<i32>> + 'a pub fn spawn_from_sync<'a, F: ?Sized + AsRawFd>(file: &'a F, opt: Options) -> impl IntoIterator<Item = eyre::Result<Option<i32>>> + '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 { match child {
Ok(mut 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) => { Err(err) => {
if_trace!(error!("Failed to spawn child: {err}")); if_trace!(error!("Failed to spawn child: {err}"));
Err(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.") //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.")
} }

@ -172,6 +172,7 @@ fn feature_check() -> eyre::Result<()>
} }
#[inline] #[inline]
#[cfg_attr(feature="logging", instrument(skip_all, fields(fd = ?file.as_raw_fd())))]
fn try_seal_size<F: AsRawFd + ?Sized>(file: &F) -> eyre::Result<()> fn try_seal_size<F: AsRawFd + ?Sized>(file: &F) -> eyre::Result<()>
{ {
//if cfg!(feature="exec") { //if cfg!(feature="exec") {
@ -180,8 +181,7 @@ fn try_seal_size<F: AsRawFd + ?Sized>(file: &F) -> eyre::Result<()>
.with_warning(|| "This may cause consumers of -exec{} to misbehave") { .with_warning(|| "This may cause consumers of -exec{} to misbehave") {
let fd = file.as_raw_fd(); let fd = file.as_raw_fd();
if_trace!{{ if_trace!{{
warn!("Failed to seal file descriptor {fd}: {err}"); warn!("Failed to seal file descriptor {fd}: {err}\n\t{err:?}");
eprintln!("\t{err:?}");
}} }}
Err(err).wrap_err("Failed to seal file's length") Err(err).wrap_err("Failed to seal file's length")
} else { } else {

Loading…
Cancel
Save