Skip to main content

relibc/
error.rs

1use alloc::boxed::Box;
2
3use crate::{header::errno::STR_ERROR, platform::types::c_int};
4
5/// Positive error codes (EINVAL, not -EINVAL).
6#[derive(Debug, Eq, PartialEq)]
7// TODO: Move to a more generic place.
8pub struct Errno(pub c_int);
9
10impl Errno {
11    pub fn sync(self) -> Self {
12        crate::platform::ERRNO.set(self.0);
13        self
14    }
15}
16
17pub type Result<T, E = Errno> = core::result::Result<T, E>;
18
19#[cfg(target_os = "redox")]
20impl From<syscall::Error> for Errno {
21    #[inline]
22    fn from(value: syscall::Error) -> Self {
23        Errno(value.errno)
24    }
25}
26#[cfg(target_os = "redox")]
27impl From<Errno> for syscall::Error {
28    #[inline]
29    fn from(value: Errno) -> Self {
30        syscall::Error::new(value.0)
31    }
32}
33
34impl From<Errno> for crate::io::Error {
35    #[inline]
36    fn from(Errno(errno): Errno) -> Self {
37        Self::from_raw_os_error(errno)
38    }
39}
40
41// TODO: core::error::Error
42
43impl core::fmt::Display for Errno {
44    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
45        match usize::try_from(self.0).ok().and_then(|i| STR_ERROR.get(i)) {
46            Some(desc) => write!(f, "{desc}"),
47            None => write!(f, "unknown error ({})", self.0),
48        }
49    }
50}
51
52pub trait ResultExt<T> {
53    fn or_minus_one_errno(self) -> T;
54}
55impl<T: From<i8>> ResultExt<T> for Result<T, Errno> {
56    fn or_minus_one_errno(self) -> T {
57        match self {
58            Self::Ok(v) => v,
59            Self::Err(Errno(errno)) => {
60                crate::platform::ERRNO.set(errno);
61                T::from(-1)
62            }
63        }
64    }
65}
66pub trait ResultExtPtrMut<T> {
67    fn or_errno_null_mut(self) -> *mut T;
68}
69impl<T> ResultExtPtrMut<T> for Result<*mut T, Errno> {
70    fn or_errno_null_mut(self) -> *mut T {
71        match self {
72            Self::Ok(ptr) => ptr,
73            Self::Err(Errno(errno)) => {
74                crate::platform::ERRNO.set(errno);
75                core::ptr::null_mut()
76            }
77        }
78    }
79}
80impl<T> ResultExtPtrMut<T> for Result<Box<T>, Errno> {
81    fn or_errno_null_mut(self) -> *mut T {
82        match self {
83            Self::Ok(ptr) => Box::into_raw(ptr),
84            Self::Err(Errno(errno)) => {
85                crate::platform::ERRNO.set(errno);
86                core::ptr::null_mut()
87            }
88        }
89    }
90}