#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[derive(Deserialize, Serialize)]
#[serde(deny_unknown_fields)]
pub enum ChildStatus
{
Continued,
Exited
{
exit_code: u8,
},
Stopped
{
signal: Signal,
ptrace_event_if_sigtrap: Option<u8>,
},
Signalled
{
signal: Signal,
core_dump: bool,
},
}
impl ParseNumber for ChildStatus
{
#[inline(always)]
fn parse_number(bytes: &[u8], radix: Radix, parse_byte: impl Fn(Radix, u8) -> Result<u8, ParseNumberError>) -> Result<Self, ParseNumberError>
{
let value = i32::parse_number(bytes, radix, parse_byte)?;
Self::parse(value).map_err(|_| ParseNumberError::OutOfRange)
}
}
impl ParseNumberOption for ChildStatus
{
#[inline(always)]
fn parse_number_option(bytes: &[u8], radix: Radix, parse_byte: impl Fn(Radix, u8) -> Result<u8, ParseNumberError>) -> Result<Option<Self>, ParseNumberError>
{
let value = i32::parse_number(bytes, radix, parse_byte)?;
if unlikely!(value == 0)
{
Ok(None)
}
else
{
Ok(Some(ChildStatus::parse(value).map_err(|_| ParseNumberError::OutOfRange)?))
}
}
}
impl ChildStatus
{
pub(crate) fn parse(status: i32) -> Result<Self, OutOfRangeSignalNumberError>
{
use self::ChildStatus::*;
let WIFCONTINUED = status == 0xFFFF;
if WIFCONTINUED
{
return Ok(Continued)
}
let WIFSTOPPED = (status & 0xFF) == 0x7F;
if WIFSTOPPED
{
let WSTOPSIG = (status >> 8) & 0xFF;
let raw_signal_number = Signal::parse_raw_signal_number_u8(WSTOPSIG as u8)?;
let ptrace_event_if_sigtrap = if raw_signal_number == Signal::SIGTRAP
{
Some(((((status >> 8) as u32) & !(Signal::SIGTRAP_ as u32)) >> 8) as u8)
}
else
{
None
};
return Ok
(
Stopped
{
signal: raw_signal_number,
ptrace_event_if_sigtrap,
}
)
}
let WIFEXITED = (status & 0x7F) == 0;
if WIFEXITED
{
let WEXITSTATUS = (status >> 8) & 0xFF;
return Ok
(
Exited
{
exit_code: WEXITSTATUS as u8
}
)
}
let WIFSIGNALED = ((status & 0x7F) + 1) as i8 >= 2;
if WIFSIGNALED
{
let WTERMSIG = status & 0x7F;
let WCOREDUMP = (status & 0x80) != 0;
let raw_signal_number_u7 = WTERMSIG as u8;
debug_assert!(raw_signal_number_u7 != 0, "Already tested for zero with `WIFEXITED`");
return
Ok
(
Signalled
{
signal: Signal::parse_raw_signal_number_non_zero_u7(new_non_zero_u8(raw_signal_number_u7))?,
core_dump: WCOREDUMP,
}
)
}
unreachable_code(format_args!("Should not be a possible state"))
}
}