Make exit status interpretable by CommandConfigurator (#2723)
* Make exit status interpretable by CommandConfigurator * Fix import issues * Fix default implementation for non-unix environment * Make docs only available on unix if the entry is only for unix * Revert "Fix default implementation for non-unix environment" This reverts commit 5457f6f7376c2a3a4d4c8459de46d6b54bb0d44f. * Fix the invalid link in the example
This commit is contained in:
parent
94fa4014ac
commit
0d0bbf0c5d
@ -38,7 +38,9 @@ use typed_builder::TypedBuilder;
|
||||
|
||||
use super::HasTimeout;
|
||||
#[cfg(all(feature = "std", unix))]
|
||||
use crate::executors::{Executor, ExitKind};
|
||||
use crate::executors::Executor;
|
||||
#[cfg(all(feature = "std", any(unix, doc)))]
|
||||
use crate::executors::ExitKind;
|
||||
use crate::{
|
||||
corpus::Corpus,
|
||||
executors::{hooks::ExecutorHooksTuple, HasObservers},
|
||||
@ -337,8 +339,6 @@ where
|
||||
OT: Debug + ObserversTuple<I, S>,
|
||||
{
|
||||
fn execute_input_with_command(&mut self, state: &mut S, input: &I) -> Result<ExitKind, Error> {
|
||||
use std::os::unix::prelude::ExitStatusExt;
|
||||
|
||||
use wait_timeout::ChildExt;
|
||||
|
||||
*state.executions_mut() += 1;
|
||||
@ -346,29 +346,21 @@ where
|
||||
|
||||
let mut child = self.configurer.spawn_child(input)?;
|
||||
|
||||
let res = match child
|
||||
let exit_kind = child
|
||||
.wait_timeout(self.configurer.exec_timeout())
|
||||
.expect("waiting on child failed")
|
||||
.map(|status| status.signal())
|
||||
{
|
||||
// for reference: https://www.man7.org/linux/man-pages/man7/signal.7.html
|
||||
Some(Some(9)) => Ok(ExitKind::Oom),
|
||||
Some(Some(_)) => Ok(ExitKind::Crash),
|
||||
Some(None) => Ok(ExitKind::Ok),
|
||||
None => {
|
||||
.map(|status| self.configurer.exit_kind_from_status(&status))
|
||||
.unwrap_or_else(|| {
|
||||
// if this fails, there is not much we can do. let's hope it failed because the process finished
|
||||
// in the meantime.
|
||||
drop(child.kill());
|
||||
// finally, try to wait to properly clean up system resources.
|
||||
drop(child.wait());
|
||||
Ok(ExitKind::Timeout)
|
||||
}
|
||||
};
|
||||
ExitKind::Timeout
|
||||
});
|
||||
|
||||
if let Ok(exit_kind) = res {
|
||||
self.observers
|
||||
.post_exec_child_all(state, input, &exit_kind)?;
|
||||
}
|
||||
self.observers
|
||||
.post_exec_child_all(state, input, &exit_kind)?;
|
||||
|
||||
if let Some(h) = &mut self.configurer.stdout_observer() {
|
||||
let mut stdout = Vec::new();
|
||||
@ -392,7 +384,7 @@ where
|
||||
let obs = observers.index_mut(h);
|
||||
obs.observe_stderr(&stderr);
|
||||
}
|
||||
res
|
||||
Ok(exit_kind)
|
||||
}
|
||||
}
|
||||
|
||||
@ -809,7 +801,7 @@ impl CommandExecutorBuilder {
|
||||
/// MyExecutor.into_executor(())
|
||||
/// }
|
||||
/// ```
|
||||
#[cfg(all(feature = "std", any(unix, doc)))]
|
||||
#[cfg(all(feature = "std", unix))]
|
||||
pub trait CommandConfigurator<I, C = Child>: Sized {
|
||||
/// Get the stdout
|
||||
fn stdout_observer(&self) -> Option<Handle<StdOutObserver>> {
|
||||
@ -828,6 +820,18 @@ pub trait CommandConfigurator<I, C = Child>: Sized {
|
||||
/// Set the timeout duration for execution of the child process.
|
||||
fn exec_timeout_mut(&mut self) -> &mut Duration;
|
||||
|
||||
/// Maps the exit status of the child process to an `ExitKind`.
|
||||
#[inline]
|
||||
fn exit_kind_from_status(&self, status: &std::process::ExitStatus) -> ExitKind {
|
||||
use crate::std::os::unix::process::ExitStatusExt;
|
||||
match status.signal() {
|
||||
// for reference: https://www.man7.org/linux/man-pages/man7/signal.7.html
|
||||
Some(9) => ExitKind::Oom,
|
||||
Some(_) => ExitKind::Crash,
|
||||
None => ExitKind::Ok,
|
||||
}
|
||||
}
|
||||
|
||||
/// Create an `Executor` from this `CommandConfigurator`.
|
||||
fn into_executor<OT, S>(self, observers: OT) -> CommandExecutor<OT, S, Self, (), C>
|
||||
where
|
||||
|
@ -5,7 +5,7 @@ use alloc::vec::Vec;
|
||||
use core::{fmt::Debug, time::Duration};
|
||||
|
||||
pub use combined::CombinedExecutor;
|
||||
#[cfg(all(feature = "std", any(unix, doc)))]
|
||||
#[cfg(all(feature = "std", unix))]
|
||||
pub use command::CommandExecutor;
|
||||
pub use differential::DiffExecutor;
|
||||
#[cfg(all(feature = "std", feature = "fork", unix))]
|
||||
@ -23,7 +23,7 @@ pub use with_observers::WithObservers;
|
||||
use crate::{state::UsesState, Error};
|
||||
|
||||
pub mod combined;
|
||||
#[cfg(all(feature = "std", any(unix, doc)))]
|
||||
#[cfg(all(feature = "std", unix))]
|
||||
pub mod command;
|
||||
pub mod differential;
|
||||
#[cfg(all(feature = "std", feature = "fork", unix))]
|
||||
|
@ -2,7 +2,10 @@
|
||||
//!
|
||||
//! The [`StdOutObserver`] and [`StdErrObserver`] observers look at the stdout of a program
|
||||
//! The executor must explicitly support these observers.
|
||||
//! For example, they are supported on the [`crate::executors::CommandExecutor`].
|
||||
#![cfg_attr(
|
||||
all(feature = "std", unix),
|
||||
doc = r"For example, they are supported on the [`crate::executors::CommandExecutor`]."
|
||||
)]
|
||||
|
||||
use alloc::borrow::Cow;
|
||||
use std::vec::Vec;
|
||||
|
Loading…
x
Reference in New Issue
Block a user