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::fmt::{Arguments, Write};
11
12use crate::process::stdio::sysget_stderr;
13
14pub mod errors {
15    pub use safa_abi::errors::{ErrorStatus, SysResult};
16
17    #[cfg(any(feature = "rustc-dep-of-std", feature = "std"))]
18    #[cfg_attr(feature = "rustc-dep-of-std", macro_export)]
19    macro_rules! err_from_io_error_kind {
20        ($io_err_ty: path, $io_err: ident) => {
21            use $crate::errors::ErrorStatus::*;
22            use $io_err_ty as IoErrorKind;
23
24            return match $io_err {
25                IoErrorKind::NotFound => NoSuchAFileOrDirectory,
26                IoErrorKind::AlreadyExists => AlreadyExists,
27                IoErrorKind::PermissionDenied => MissingPermissions,
28                IoErrorKind::ResourceBusy => Busy,
29                IoErrorKind::NotADirectory => NotADirectory,
30                IoErrorKind::IsADirectory => NotAFile,
31                IoErrorKind::OutOfMemory => OutOfMemory,
32                IoErrorKind::Other => Generic,
33                IoErrorKind::DirectoryNotEmpty => DirectoryNotEmpty,
34                IoErrorKind::Unsupported => OperationNotSupported,
35
36                _ => Generic,
37            };
38        };
39    }
40
41    #[cfg(feature = "std")]
42    pub fn err_from_io_error_kind(io_err: std::io::ErrorKind) -> ErrorStatus {
43        err_from_io_error_kind!(std::io::ErrorKind, io_err);
44    }
45}
46
47pub mod alloc;
48pub mod process;
49pub mod sync;
50pub mod syscalls;
51pub use safa_abi as abi;
52pub use safa_abi::ffi;
53
54#[macro_export]
55macro_rules! exported_func {
56    {$($meta: meta)? $($inner: tt)*} => {
57        $($meta)?
58        #[cfg_attr(
59            not(any(feature = "std", feature = "rustc-dep-of-std")),
60            unsafe(no_mangle)
61        )]
62        #[cfg_attr(any(feature = "std", feature = "rustc-dep-of-std"), inline(always))]
63        $($inner)*
64    };
65}
66
67#[allow(unused)]
68struct Stderr;
69
70fn _print_err(str: &str) {
71    let stderr = sysget_stderr();
72    _ = syscalls::io::write(stderr, -1, str.as_bytes());
73    _ = syscalls::io::sync(stderr);
74}
75impl Write for Stderr {
76    fn write_str(&mut self, s: &str) -> core::fmt::Result {
77        _print_err(s);
78        Ok(())
79    }
80}
81
82#[doc(hidden)]
83pub fn _write_stderr(args: Arguments) {
84    _ = Stderr.write_fmt(args);
85}
86
87#[macro_export]
88#[allow(unused)]
89macro_rules! printerr {
90    ($($arg:tt)*) => {
91        $crate::_write_stderr(format_args!($($arg)*));
92    };
93}
94
95#[macro_export]
96#[allow(unused)]
97macro_rules! printerrln {
98    () => {
99        $crate::printerr!("\n");
100    };
101    ($($arg:tt)*) => {
102        $crate::printerr!("{}\n", format_args!($($arg)*));
103    };
104}
105
106#[cfg(not(any(feature = "std", feature = "rustc-dep-of-std")))]
107#[panic_handler]
108fn _panic(info: &core::panic::PanicInfo) -> ! {
109    printerrln!("Safa-API panicked: {}", info);
110    syscalls::process::exit(1);
111}