Add ABI structs for signals

This commit is contained in:
Mark Poliakov 2023-07-25 16:14:48 +03:00
parent 91a4a93569
commit 9bf3840376
2 changed files with 84 additions and 1 deletions

View File

@ -1,6 +1,18 @@
//! Data structures for process management
use crate::io::RawFd;
use core::num::NonZeroI32;
use crate::{io::RawFd, primitive_enum};
/// Code signalled by a process when it finishes or is terminated by a signal
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(C)]
pub enum ExitCode {
/// Process exited normally, either with an error or with a 0
Exited(i32),
/// Process was killed by a signal
BySignal(Signal),
}
/// Defines an optional argument for controlling process creation
#[derive(Debug)]
@ -14,6 +26,30 @@ pub enum SpawnOption {
},
}
primitive_enum! {
#[doc = "Defines signal numbers sent to processes"]
pub enum Signal: u32 {
#[doc = "Process has tried to perform an illegal memory operation"]
MemoryAccessViolation = 1,
#[doc = "Process has hit a breakpoint or was aborted"]
Aborted = 2,
#[doc = "Process was killed"]
Killed = 3,
}
}
/// Data provided by the kernel to signal entry function
#[derive(Clone, Debug)]
#[repr(C)]
pub struct SignalEntryData {
/// Which signal was issued
pub signal: Signal,
/// Optional argument of the signal
///
/// * For [Signal::MemoryAccessViolation], contains the fault address
pub data: Option<usize>,
}
/// Controls how processes are created
#[derive(Clone, Debug)]
#[repr(C)]
@ -25,3 +61,43 @@ pub struct SpawnOptions<'a> {
/// Optional arguments to specify details of the creation
pub optional: &'a [SpawnOption],
}
impl ExitCode {
/// Returned when a process has exited successfully
pub const SUCCESS: Self = Self::Exited(0);
/// Returns `true` if this ExitCode signals a successful exit
pub const fn is_success(self) -> bool {
matches!(self, Self::Exited(0))
}
/// Returns [Some] if the process exited with an error or was killed by a signal
pub fn as_failure(self) -> Option<NonZeroI32> {
match self {
Self::Exited(0) => None,
Self::Exited(n) => Some(unsafe { NonZeroI32::new_unchecked(n) }),
Self::BySignal(sig) => {
Some(unsafe { NonZeroI32::new_unchecked(u32::from(sig) as i32) })
}
}
}
}
impl From<i32> for ExitCode {
fn from(value: i32) -> Self {
match value {
-255..=255 => Self::Exited(value),
10000.. => Self::BySignal(Signal::try_from(value as u32 - 10000).unwrap()),
_ => todo!(),
}
}
}
impl From<ExitCode> for i32 {
fn from(value: ExitCode) -> Self {
match value {
ExitCode::BySignal(signal) => 10000 + u32::from(signal) as i32,
ExitCode::Exited(value) => value,
}
}
}

View File

@ -37,8 +37,15 @@ primitive_enum!(
Spawn = 15,
#[doc = "Wait for a process to exit"]
WaitProcess = 16,
#[doc = "Send a signal to a process"]
SendSignal = 17,
#[doc = "Setup a signal entry for the caller process"]
SetSignalEntry = 18,
#[doc = "Exit from a syscall handler"]
ExitSignal = 19,
#[doc = "Get the caller process PID"]
GetPid = 20,
#[doc = "Mount a filesystem"]
Mount = 101,