logboi/
lib.rs

1#[link(name = "logboi_srv")]
2extern "C" {}
3
4use secgate::util::{Descriptor, Handle, SimpleBuffer};
5use twizzler_rt_abi::{error::TwzError, object::MapFlags};
6
7/// An open handle to the logging service.
8pub struct LogHandle {
9    desc: Descriptor,
10    buffer: SimpleBuffer,
11}
12
13// A service typically implements these handles via this interface.
14// You can see that internally, this is where most of the secure gate APIs
15// are actually used, so that interface is abstracted from the programmer.
16impl Handle for LogHandle {
17    type OpenError = TwzError;
18
19    type OpenInfo = ();
20
21    fn open(_info: Self::OpenInfo) -> Result<Self, Self::OpenError>
22    where
23        Self: Sized,
24    {
25        let (desc, id) = logboi_srv::logboi_open_handle()?;
26        let handle =
27            twizzler_rt_abi::object::twz_rt_map_object(id, MapFlags::READ | MapFlags::WRITE)?;
28        let sb = SimpleBuffer::new(handle);
29        Ok(Self { desc, buffer: sb })
30    }
31
32    fn release(&mut self) {
33        let _ = logboi_srv::logboi_close_handle(self.desc);
34    }
35}
36
37// On drop, release the handle.
38impl Drop for LogHandle {
39    fn drop(&mut self) {
40        self.release()
41    }
42}
43
44impl LogHandle {
45    /// Open a new logging handle.
46    pub fn new() -> Option<Self> {
47        Self::open(()).ok()
48    }
49
50    /// Send a log message via this logging handle.
51    pub fn log(&mut self, buf: &[u8]) -> Option<usize> {
52        let len = self.buffer.write(buf);
53        if len == 0 {
54            return Some(0);
55        }
56
57        if logboi_srv::logboi_post(self.desc, len).ok().is_some() {
58            Some(len)
59        } else {
60            None
61        }
62    }
63}