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 From<std::io::Error> for CoreError {
59 fn from(e: std::io::Error) -> Self {
60 Self::sys(
61 e.raw_os_error().unwrap_or(libc::EIO),
62 match e.kind() {
63 std::io::ErrorKind::NotFound => "io:not_found",
64 std::io::ErrorKind::PermissionDenied => "io:permission_denied",
65 std::io::ErrorKind::AlreadyExists => "io:already_exists",
66 std::io::ErrorKind::InvalidInput => "io:invalid_input",
67 _ => "io",
68 },
69 )
70 }
71}
72
73impl fmt::Display for CoreError {
74 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
75 match self {
76 Self::Syscall { code, op } => write!(f, "{op} failed (code={code})"),
77 Self::Binder { code, op } => write!(f, "binder {op} failed (status={code})"),
78 }
79 }
80}
81
82impl std::error::Error for CoreError {}
83
84pub mod errno {
86 pub const EADDRINUSE: i32 = libc::EADDRINUSE;
87 pub const EPIPE: i32 = libc::EPIPE;
88 pub const EAGAIN: i32 = libc::EAGAIN;
89 pub const EINTR: i32 = libc::EINTR;
90 pub const ENOENT: i32 = libc::ENOENT;
91 pub const EACCES: i32 = libc::EACCES;
92}
93
94#[inline(always)]
95pub(crate) fn syscall_ret(ret: i32, op: &'static str) -> Result<(), CoreError> {
96 if ret == -1 {
97 let code = std::io::Error::last_os_error().raw_os_error().unwrap_or(0);
98 Err(CoreError::sys(code, op))
99 } else {
100 Ok(())
101 }
102}
103
104#[inline(always)]
105pub(crate) fn posix_ret(ret: i32, op: &'static str) -> Result<(), CoreError> {
106 if ret != 0 {
107 Err(CoreError::sys(ret, op))
108 } else {
109 Ok(())
110 }
111}