1use std::fmt;
13
14#[derive(Debug, Clone, PartialEq, Eq)]
16pub enum CoreError {
17 Syscall {
19 code: i32,
21 op: &'static str,
23 },
24 Binder {
26 code: i32,
28 op: &'static str,
30 },
31}
32
33impl CoreError {
34 pub fn sys(code: i32, op: &'static str) -> Self {
36 Self::Syscall { code, op }
37 }
38
39 pub fn binder(code: i32, op: &'static str) -> Self {
41 Self::Binder { code, op }
42 }
43
44 pub fn raw_os_error(&self) -> Option<i32> {
46 match self {
47 Self::Syscall { code, .. } => Some(*code),
48 Self::Binder { .. } => None,
49 }
50 }
51
52 pub fn to_io_error(&self) -> std::io::Error {
54 std::io::Error::from_raw_os_error(self.raw_os_error().unwrap_or(libc::EIO))
55 }
56}
57
58impl fmt::Display for CoreError {
59 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
60 match self {
61 Self::Syscall { code, op } => write!(f, "{op} failed (code={code})"),
62 Self::Binder { code, op } => write!(f, "binder {op} failed (status={code})"),
63 }
64 }
65}
66
67impl std::error::Error for CoreError {}
68
69pub mod errno {
71 pub const EADDRINUSE: i32 = libc::EADDRINUSE;
72 pub const EPIPE: i32 = libc::EPIPE;
73 pub const EAGAIN: i32 = libc::EAGAIN;
74 pub const EINTR: i32 = libc::EINTR;
75 pub const ENOENT: i32 = libc::ENOENT;
76 pub const EACCES: i32 = libc::EACCES;
77}
78
79#[inline(always)]
80pub(crate) fn syscall_ret(ret: i32, op: &'static str) -> Result<(), CoreError> {
81 if ret == -1 {
82 let code = std::io::Error::last_os_error().raw_os_error().unwrap_or(0);
83 Err(CoreError::sys(code, op))
84 } else {
85 Ok(())
86 }
87}
88
89#[inline(always)]
90pub(crate) fn posix_ret(ret: i32, op: &'static str) -> Result<(), CoreError> {
91 if ret != 0 {
92 Err(CoreError::sys(ret, op))
93 } else {
94 Ok(())
95 }
96}