//! Process identity is minted from a kernel owned process ID. //! User requests may inspect an assigned identity, but cannot replace it. #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub struct Principal(u64); impl Principal { pub const fn id(self) -> u64 { self.0 } } #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub enum Error { Full, Duplicate, Unknown, Access, Exhausted, } #[derive(Clone, Copy, Debug, PartialEq, Eq)] struct Binding
{
process: P,
principal: Principal,
}
pub struct Registry {
pub fn new() -> Self {
Self { next: 1, bindings: [None; N] }
}
/// Called only after the kernel has obtained a genuine ProcessId.
pub fn bind_kernel(&mut self, process: P) -> Result {
fn default() -> Self { Self::new() }
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct Handle(u64);
impl Handle {
pub const fn id(self) -> u64 { self.0 }
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Capability {
ReadOnlyFile { object: u64, allow_child: bool },
KernelDevice { object: u64 },
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
struct Grant {
handle: Handle,
owner: P,
capability: Capability,
}
pub struct HandleSet {
pub fn new() -> Self {
Self { next: 1, grants: [None; M] }
}
pub fn issue_kernel , owner: P, capability: Capability,
) -> Result , parent: P, child: P,
actual_parent: Option , requested: u64,
) -> Result {
fn default() -> Self { Self::new() }
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct InspectHandle(u64);
impl InspectHandle {
pub const fn id(self) -> u64 { self.0 }
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct MapMetadata {
pub resource_owner: u64,
pub pages: u64,
pub published: bool,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
struct InspectGrant {
handle: InspectHandle,
observer: P,
target: P,
}
pub struct InspectSet {
pub fn new() -> Self { Self { next: 1, grants: [None; M] } }
/// Only the kernel binds a permit to two live process identities.
pub fn issue_kernel , observer: P, target: P,
) -> Result , observer: P,
actual_target: P, requested: u64,
) -> Result<(), Error> {
identities.principal(observer)?;
identities.principal(actual_target)?;
let grant = self.grants.iter().flatten()
.find(|grant| grant.handle.id() == requested && grant.observer == observer)
.ok_or(Error::Unknown)?;
if grant.target != actual_target { return Err(Error::Access); }
Ok(())
}
/// `actual_target` and `metadata` come from one live ProcessTable record.
pub fn inspect_metadata , observer: P,
actual_target: P, requested: u64, metadata: MapMetadata,
) -> Result , observer: P,
actual_target: P, requested: u64,
) -> Result<(), Error> {
self.authorize(identities, observer, actual_target, requested)?;
Err(Error::Access)
}
pub fn close_observer(&mut self, observer: P) -> usize {
let mut closed = 0;
for slot in &mut self.grants {
if slot.is_some_and(|grant| grant.observer == observer) {
*slot = None;
closed += 1;
}
}
closed
}
pub fn snapshot(&self) -> (u64, [Option<(u64, P, P)>; M]) {
(self.next, self.grants.map(|grant| grant.map(|grant|
(grant.handle.id(), grant.observer, grant.target))))
}
}
impl {
fn default() -> Self { Self::new() }
}