169 lines
4.2 KiB
Rust
Raw Normal View History

2024-03-12 13:48:09 +02:00
//! Data structures for process management
2024-11-17 23:32:07 +02:00
use core::{ffi::CStr, fmt, marker::PhantomData, time::Duration};
2024-03-12 13:48:09 +02:00
2024-11-17 23:32:07 +02:00
use crate::io::{FileMode, RawFd};
2024-03-12 13:48:09 +02:00
mod exit;
2024-11-17 23:32:07 +02:00
pub mod thread;
2024-03-12 13:48:09 +02:00
pub use crate::generated::{
ExecveOptions, ProcessGroupId, ProcessId, Signal, SignalEntryData, SpawnFlags, SpawnOptions,
ThreadId, ThreadSpawnOptions,
};
2024-03-12 13:48:09 +02:00
pub use exit::ExitCode;
2024-11-17 23:32:07 +02:00
pub use thread::ThreadOption;
// TODO this is ugly
pub mod auxv {
pub const TLS_MASTER_COPY: u64 = 0x80;
pub const TLS_FULL_SIZE: u64 = 0x81;
pub const TLS_DATA_SIZE: u64 = 0x82;
pub const TLS_ALIGN: u64 = 0x83;
pub const TLS_MODULE_ID: u64 = 0x84;
pub const TLS_MODULE_OFFSET: u64 = 0x85;
pub const TLS_ALREADY_INITIALIZED: u64 = 0x86;
pub const NULL: u64 = 0x00;
}
/// Defines an optional argument for controlling process creation
#[derive(Debug)]
pub enum SpawnOption {
/// Indicates a new process should inherit a file descriptor from its creator
InheritFile {
/// FD on the creator side
source: RawFd,
/// What FD number should be used in the child
child: RawFd,
},
/// The new process should be placed in the specified group
SetProcessGroup(ProcessGroupId),
/// Gain terminal control for the given FD
GainTerminal(RawFd),
/// Attach debugging to a channel in parent's I/O context. The process will start in
/// single-stepping mode
AttachDebug(RawFd),
}
2024-03-12 13:48:09 +02:00
/// Describes a single mutex operation
#[derive(Clone, Debug)]
#[repr(C)]
pub enum MutexOperation {
/// Waits on the mutex object until it is different from "compare value"
Wait(u32, Option<Duration>),
/// Waits on the mutex object until it becomes equal to the "compare value"
WaitUntil(u32, Option<Duration>),
2024-03-12 13:48:09 +02:00
/// Wakes a single mutex-waiting thread
Wake,
/// Wakes all threads waiting on the mutex
WakeAll,
}
/// Provides some amount of process-related information
#[derive(Clone, Debug)]
pub enum ProcessInfoElement {
/// Mask applied to file modes when creating new files/directories
Umask(FileMode),
}
2024-11-17 23:32:07 +02:00
#[derive(Debug, Clone, Copy)]
#[repr(C)]
pub struct AuxValue {
pub tag: u64,
pub val: u64,
}
#[derive(Clone, Copy)]
pub struct StringArgIter<'a> {
ptr: *const *const u8,
_pd: PhantomData<&'a ProgramArgumentInner>,
}
#[derive(Clone, Copy)]
pub struct AuxValueIter<'a> {
ptr: *const AuxValue,
_pd: PhantomData<&'a ProgramArgumentInner>,
}
#[repr(C)]
pub struct ProgramArgumentInner {
pub args: *const *const u8,
pub envs: *const *const u8,
pub auxv: *const AuxValue,
2024-03-12 13:48:09 +02:00
}
impl ProcessId {
pub const ZERO: Self = Self(0);
}
impl fmt::Display for ProcessId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "<Process {}>", self.0)
}
}
impl fmt::Display for ProcessGroupId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "<Process group {}>", self.0)
}
}
2024-11-17 23:32:07 +02:00
impl<'a> Iterator for StringArgIter<'a> {
type Item = &'a CStr;
fn next(&mut self) -> Option<Self::Item> {
if self.ptr.is_null() {
return None;
}
let entry = unsafe { self.ptr.read() };
if entry.is_null() {
return None;
}
self.ptr = unsafe { self.ptr.add(1) };
let entry = unsafe { CStr::from_ptr(entry.cast()) };
Some(entry)
}
}
impl<'a> Iterator for AuxValueIter<'a> {
type Item = &'a AuxValue;
fn next(&mut self) -> Option<Self::Item> {
if self.ptr.is_null() {
return None;
}
let entry = unsafe { &*self.ptr };
if entry.tag == auxv::NULL {
return None;
}
self.ptr = unsafe { self.ptr.add(1) };
Some(entry)
}
}
impl ProgramArgumentInner {
pub fn args(&self) -> impl Iterator<Item = &CStr> {
StringArgIter {
ptr: self.args,
_pd: PhantomData,
}
}
pub fn envs(&self) -> impl Iterator<Item = &CStr> {
StringArgIter {
ptr: self.envs,
_pd: PhantomData,
}
}
pub fn auxv(&self) -> impl Iterator<Item = &AuxValue> {
AuxValueIter {
ptr: self.auxv,
_pd: PhantomData,
}
}
}