blob: 3065b59799b6b06644a4c217bd7f714ed7afea65 [file]
// Copyright 2026 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
use crate::ptrace::PtraceEvent;
use crate::signals::SignalInfo;
use starnix_uapi::{CLD_CONTINUED, CLD_DUMPED, CLD_EXITED, CLD_KILLED, CLD_STOPPED};
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum ExitStatus {
Exit(u8),
Kill(SignalInfo),
CoreDump(SignalInfo),
// The second field for Stop and Continue contains the type of ptrace stop
// event that made it stop / continue, if applicable (PTRACE_EVENT_STOP,
// PTRACE_EVENT_FORK, etc)
Stop(SignalInfo, PtraceEvent),
Continue(SignalInfo, PtraceEvent),
}
impl ExitStatus {
/// Converts the given exit status to a status code suitable for returning from wait syscalls.
pub fn wait_status(&self) -> i32 {
match self {
ExitStatus::Exit(status) => (*status as i32) << 8,
ExitStatus::Kill(siginfo) => siginfo.signal.number() as i32,
ExitStatus::CoreDump(siginfo) => (siginfo.signal.number() as i32) | 0x80,
ExitStatus::Continue(siginfo, trace_event) => {
let trace_event_val = *trace_event as u32;
if trace_event_val != 0 {
(siginfo.signal.number() as i32) | (trace_event_val << 16) as i32
} else {
0xffff
}
}
ExitStatus::Stop(siginfo, trace_event) => {
let trace_event_val = *trace_event as u32;
(0x7f + ((siginfo.signal.number() as i32) << 8)) | (trace_event_val << 16) as i32
}
}
}
pub fn signal_info_code(&self) -> i32 {
match self {
ExitStatus::Exit(_) => CLD_EXITED as i32,
ExitStatus::Kill(_) => CLD_KILLED as i32,
ExitStatus::CoreDump(_) => CLD_DUMPED as i32,
ExitStatus::Stop(_, _) => CLD_STOPPED as i32,
ExitStatus::Continue(_, _) => CLD_CONTINUED as i32,
}
}
pub fn signal_info_status(&self) -> i32 {
match self {
ExitStatus::Exit(status) => *status as i32,
ExitStatus::Kill(siginfo)
| ExitStatus::CoreDump(siginfo)
| ExitStatus::Continue(siginfo, _)
| ExitStatus::Stop(siginfo, _) => siginfo.signal.number() as i32,
}
}
}
impl Default for ExitStatus {
fn default() -> Self {
Self::Exit(0)
}
}