strat9_kernel/namespace/
mod.rs1use crate::{sync::SpinLock, syscall::error::SyscallError};
6use alloc::{
7 collections::BTreeMap,
8 string::{String, ToString},
9};
10
11struct Namespace {
12 bindings: BTreeMap<String, u64>,
13}
14
15impl Namespace {
16 const fn new() -> Self {
18 Namespace {
19 bindings: BTreeMap::new(),
20 }
21 }
22}
23
24static NAMESPACE: SpinLock<Namespace> = SpinLock::new(Namespace::new());
25
26pub fn bind(path: &str, port_id: u64) -> Result<(), SyscallError> {
28 if path.is_empty() || !path.starts_with('/') {
29 return Err(SyscallError::InvalidArgument);
30 }
31 let mut ns = NAMESPACE.lock();
32 ns.bindings.insert(path.to_string(), port_id);
33 Ok(())
34}
35
36pub fn unbind(path: &str) -> Result<(), SyscallError> {
38 let mut ns = NAMESPACE.lock();
39 ns.bindings.remove(path).ok_or(SyscallError::BadHandle)?;
40 Ok(())
41}
42
43pub fn list_all_bindings() -> alloc::vec::Vec<(String, u64)> {
45 let ns = NAMESPACE.lock();
46 ns.bindings.iter().map(|(k, v)| (k.clone(), *v)).collect()
47}
48
49pub fn resolve(path: &str) -> Option<(u64, String)> {
53 let ns = NAMESPACE.lock();
54 let mut best: Option<(&String, &u64)> = None;
55 for (prefix, port) in ns.bindings.iter() {
56 if path.starts_with(prefix) {
57 if path.len() == prefix.len() || path.as_bytes().get(prefix.len()) == Some(&b'/') {
59 match best {
60 Some((best_prefix, _)) if best_prefix.len() >= prefix.len() => {}
61 _ => best = Some((prefix, port)),
62 }
63 }
64 }
65 }
66 best.map(|(prefix, port)| {
67 let remaining = path[prefix.len()..].to_string();
68 (*port, remaining)
69 })
70}