1pub use self::abi::*;
2pub use self::pid::*;
3pub use self::process::*;
4pub use self::thread::*;
5
6use crate::event::{Event, EventSet};
7use crate::lock::{MappedMutex, Mutex, MutexGuard};
8use crate::signal::Signal;
9use crate::subsystem::Subsystem;
10use alloc::sync::{Arc, Weak};
11use core::error::Error;
12use core::fmt::{Display, Formatter};
13use hashbrown::HashMap;
14use macros::bitflag;
15use rustc_hash::FxBuildHasher;
16
17mod abi;
18mod cell;
19mod pid;
20mod process;
21mod thread;
22
23pub struct ProcMgr {
25 procs: Mutex<HashMap<Pid, Weak<Proc>, FxBuildHasher>>, events: Arc<EventSet<ProcEvents>>,
27}
28
29impl ProcMgr {
30 pub fn new() -> Arc<Self> {
31 let events = Arc::default();
32
33 Arc::new(Self {
34 procs: Mutex::new(HashMap::with_hasher(FxBuildHasher)),
35 events,
36 })
37 }
38
39 pub fn list(&self) -> MappedMutex<'_, impl ExactSizeIterator<Item = &Weak<Proc>>> {
40 MutexGuard::map(self.procs.lock(), |procs| procs.values())
41 }
42
43 pub fn fork(&self, abi: Arc<dyn ProcAbi>, flags: Fork) -> Result<Arc<Proc>, ForkError> {
52 if (u32::from(flags) & 0x60008f8b) != 0
54 || flags.has_all(Fork::CopyFd | Fork::ClearFd)
55 || flags.has_any(Fork::ParentSignal.mask()) && !flags.has_any(Fork::CustomSignal)
56 {
57 return Err(ForkError::InvalidFlags);
58 }
59
60 if !flags.has_any(Fork::CreateProcess) {
61 todo!()
62 }
63
64 Ok(Proc::new(abi, &self.events))
66 }
67}
68
69impl Subsystem for ProcMgr {}
70
71#[derive(Default)]
73pub struct ProcEvents {
74 pub process_init: Event<fn(&mut Proc)>,
75 pub process_ctor: Event<fn(&Weak<Proc>)>,
76}
77
78#[bitflag(u32)]
80pub enum Fork {
81 CopyFd = 0x4,
86 CreateProcess = 0x10,
90 ClearFd = 0x1000,
95 CustomSignal = 0x80000,
99 ParentSignal(Signal) = 0xFF00000,
104}
105
106#[derive(Debug)]
108pub enum ForkError {
109 InvalidFlags,
110}
111
112impl Error for ForkError {}
113
114impl Display for ForkError {
115 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
116 match self {
117 Self::InvalidFlags => f.write_str("invalid flags"),
118 }
119 }
120}