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
69#[inline(always)]
70pub(crate) fn syscall_ret(ret: i32, op: &'static str) -> Result<(), CoreError> {
71 if ret == -1 {
72 let code = std::io::Error::last_os_error().raw_os_error().unwrap_or(0);
73 Err(CoreError::sys(code, op))
74 } else {
75 Ok(())
76 }
77}
78
79#[inline(always)]
80pub(crate) fn posix_ret(ret: i32, op: &'static str) -> Result<(), CoreError> {
81 if ret != 0 {
82 Err(CoreError::sys(ret, op))
83 } else {
84 Ok(())
85 }
86}