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;
15
16mod abi;
17mod cell;
18mod pid;
19mod process;
20mod thread;
21
22pub struct ProcMgr {
24 procs: Mutex<HashMap<Pid, Weak<Proc>>>, events: Arc<EventSet<ProcEvents>>,
26}
27
28impl ProcMgr {
29 pub fn new() -> Arc<Self> {
30 let events = Arc::default();
31
32 Arc::new(Self {
33 procs: Mutex::new(HashMap::new()),
34 events,
35 })
36 }
37
38 pub fn list(&self) -> MappedMutex<impl ExactSizeIterator<Item = &Weak<Proc>> + '_> {
39 MutexGuard::map(self.procs.lock(), |procs| procs.values())
40 }
41
42 pub fn fork(&self, abi: Arc<dyn ProcAbi>, flags: Fork) -> Result<Arc<Proc>, ForkError> {
51 if (u32::from(flags) & 0x60008f8b) != 0
53 || flags.has_all(Fork::CopyFd | Fork::ClearFd)
54 || flags.has_any(Fork::ParentSignal.mask()) && !flags.has_any(Fork::CustomSignal)
55 {
56 return Err(ForkError::InvalidFlags);
57 }
58
59 if !flags.has_any(Fork::CreateProcess) {
60 todo!()
61 }
62
63 Ok(Proc::new(abi, &self.events))
65 }
66}
67
68impl Subsystem for ProcMgr {}
69
70#[derive(Default)]
72pub struct ProcEvents {
73 pub process_init: Event<fn(&mut Proc)>,
74 pub process_ctor: Event<fn(&Weak<Proc>)>,
75}
76
77#[bitflag(u32)]
79pub enum Fork {
80 CopyFd = 0x4,
85 CreateProcess = 0x10,
89 ClearFd = 0x1000,
94 CustomSignal = 0x80000,
98 ParentSignal(Signal) = 0xFF00000,
103}
104
105#[derive(Debug)]
107pub enum ForkError {
108 InvalidFlags,
109}
110
111impl Error for ForkError {}
112
113impl Display for ForkError {
114 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
115 match self {
116 Self::InvalidFlags => f.write_str("invalid flags"),
117 }
118 }
119}