1use std::sync::OnceLock;
2
3use monitor_api::CompartmentHandle;
4use secgate::{util::Descriptor, DynamicSecGate};
5use twizzler_rt_abi::object::ObjID;
6
7use crate::{api::NamerAPI, handle::NamingHandle, GetFlags, NsNode, Result};
8
9pub struct DynamicNamerAPI {
10 _handle: &'static CompartmentHandle,
11 put: DynamicSecGate<'static, (Descriptor, usize, ObjID), ()>,
12 mkns: DynamicSecGate<'static, (Descriptor, usize, bool), ()>,
13 link: DynamicSecGate<'static, (Descriptor, usize, usize), ()>,
14 get: DynamicSecGate<'static, (Descriptor, usize, GetFlags), NsNode>,
15 open_handle: DynamicSecGate<'static, (), (Descriptor, ObjID)>,
16 close_handle: DynamicSecGate<'static, (Descriptor,), ()>,
17 enumerate_names: DynamicSecGate<'static, (Descriptor, usize), usize>,
18 enumerate_names_nsid: DynamicSecGate<'static, (Descriptor, ObjID), usize>,
19 remove: DynamicSecGate<'static, (Descriptor, usize), ()>,
20 change_namespace: DynamicSecGate<'static, (Descriptor, usize), ()>,
21}
22
23impl NamerAPI for DynamicNamerAPI {
24 fn put(&self, desc: Descriptor, name_len: usize, id: ObjID) -> Result<()> {
25 (self.put)(desc, name_len, id)
26 }
27
28 fn get(&self, desc: Descriptor, name_len: usize, flags: GetFlags) -> Result<NsNode> {
29 (self.get)(desc, name_len, flags)
30 }
31
32 fn open_handle(&self) -> Result<(Descriptor, ObjID)> {
33 (self.open_handle)()
34 }
35
36 fn close_handle(&self, desc: Descriptor) -> Result<()> {
37 let _ = (self.close_handle)(desc);
38 Ok(())
39 }
40
41 fn enumerate_names(&self, desc: Descriptor, name_len: usize) -> Result<usize> {
42 (self.enumerate_names)(desc, name_len)
43 }
44
45 fn enumerate_names_nsid(&self, desc: Descriptor, id: ObjID) -> Result<usize> {
46 (self.enumerate_names_nsid)(desc, id)
47 }
48
49 fn remove(&self, desc: Descriptor, name_len: usize) -> Result<()> {
50 (self.remove)(desc, name_len)
51 }
52
53 fn change_namespace(&self, desc: Descriptor, name_len: usize) -> Result<()> {
54 (self.change_namespace)(desc, name_len)
55 }
56
57 fn mkns(&self, desc: Descriptor, name_len: usize, persist: bool) -> Result<()> {
58 (self.mkns)(desc, name_len, persist)
59 }
60
61 fn link(&self, desc: Descriptor, name_len: usize, link_name: usize) -> Result<()> {
62 (self.link)(desc, name_len, link_name)
63 }
64}
65
66static DYNAMIC_NAMER_API: OnceLock<DynamicNamerAPI> = OnceLock::new();
67
68pub fn dynamic_namer_api() -> &'static DynamicNamerAPI {
69 DYNAMIC_NAMER_API.get_or_init(|| {
70 let handle = Box::leak(Box::new(
71 CompartmentHandle::lookup("naming").expect("failed to open namer compartment"),
72 ));
73 DynamicNamerAPI {
74 _handle: handle,
75 put: unsafe {
76 handle
77 .dynamic_gate("put")
78 .expect("failed to find put gate call")
79 },
80 mkns: unsafe {
81 handle
82 .dynamic_gate("mkns")
83 .expect("failed to find put gate call")
84 },
85 link: unsafe {
86 handle
87 .dynamic_gate("link")
88 .expect("failed to find put gate call")
89 },
90 get: unsafe {
91 handle
92 .dynamic_gate("get")
93 .expect("failed to find get gate call")
94 },
95 open_handle: unsafe {
96 handle
97 .dynamic_gate::<(), (Descriptor, ObjID)>("open_handle")
98 .expect("failed to find open_handle gate call")
99 },
100 close_handle: unsafe {
101 handle
102 .dynamic_gate::<(Descriptor,), ()>("close_handle")
103 .expect("failed to find close_handle gate call")
104 },
105 enumerate_names: unsafe {
106 handle
107 .dynamic_gate("enumerate_names")
108 .expect("failed to find enumerate_names gate call")
109 },
110 enumerate_names_nsid: unsafe {
111 handle
112 .dynamic_gate("enumerate_names_nsid")
113 .expect("failed to find enumerate_names gate call")
114 },
115 remove: unsafe {
116 handle
117 .dynamic_gate("remove")
118 .expect("failed to find remove gate call")
119 },
120 change_namespace: unsafe {
121 handle
122 .dynamic_gate("change_namespace")
123 .expect("failed to find change_namespace gate call")
124 },
125 }
126 })
127}
128
129pub type DynamicNamingHandle = NamingHandle<'static, DynamicNamerAPI>;
130
131pub fn dynamic_naming_factory() -> Option<DynamicNamingHandle> {
132 NamingHandle::new(dynamic_namer_api())
133}