safa_api/
lib.rs

1//! A high-level API over SafaOS's syscalls
2//!
3//! for example [`self::alloc`] is a high-level userspace allocator which internally uses the [`self::syscalls::syssbrk`] syscall
4//!
5//! This crate also exposes raw SafaOS syscalls (see [`self::syscalls`])
6//! and raw SafaOS abi structures (see [`self::raw`])
7
8#![cfg_attr(not(feature = "std"), no_std)]
9
10use core::{cell::LazyCell, ops::Deref};
11
12pub mod errors {
13    pub use safa_abi::errors::{ErrorStatus, SysResult};
14
15    #[cfg(any(feature = "rustc-dep-of-std", feature = "std"))]
16    #[cfg_attr(feature = "rustc-dep-of-std", macro_export)]
17    macro_rules! err_from_io_error_kind {
18        ($io_err_ty: path, $io_err: ident) => {
19            use $crate::errors::ErrorStatus::*;
20            use $io_err_ty as IoErrorKind;
21
22            return match $io_err {
23                IoErrorKind::NotFound => NoSuchAFileOrDirectory,
24                IoErrorKind::AlreadyExists => AlreadyExists,
25                IoErrorKind::PermissionDenied => MissingPermissions,
26                IoErrorKind::ResourceBusy => Busy,
27                IoErrorKind::NotADirectory => NotADirectory,
28                IoErrorKind::IsADirectory => NotAFile,
29                IoErrorKind::OutOfMemory => OutOfMemory,
30                IoErrorKind::Other => Generic,
31                IoErrorKind::DirectoryNotEmpty => DirectoryNotEmpty,
32                IoErrorKind::Unsupported => OperationNotSupported,
33
34                _ => Generic,
35            };
36        };
37    }
38
39    #[cfg(feature = "std")]
40    pub fn err_from_io_error_kind(io_err: std::io::ErrorKind) -> ErrorStatus {
41        err_from_io_error_kind!(std::io::ErrorKind, io_err);
42    }
43}
44
45pub mod alloc;
46pub mod process;
47pub mod raw;
48pub mod syscalls;
49
50// FIXME: introduce locks when threads are added
51pub(crate) struct Lazy<T>(core::cell::LazyCell<T>);
52impl<T> Lazy<T> {
53    pub const fn new(value: fn() -> T) -> Self {
54        Self(core::cell::LazyCell::new(value))
55    }
56}
57
58impl<T> Deref for Lazy<T> {
59    type Target = LazyCell<T>;
60    fn deref(&self) -> &Self::Target {
61        &self.0
62    }
63}
64
65unsafe impl<T> Sync for Lazy<T> {}
66unsafe impl<T> Send for Lazy<T> {}