1pub use strat9_abi::errno::*;
2
3use num_enum::{IntoPrimitive, TryFromPrimitive};
4
5const ERRNO_MAX: isize = 4095;
6
7#[derive(Debug, Clone, Copy, PartialEq, Eq, TryFromPrimitive, IntoPrimitive, thiserror::Error)]
8#[must_use]
9#[repr(usize)]
10pub enum Error {
11 #[error("Operation not permitted")]
12 PermissionDenied = EPERM,
13 #[error("No such file or directory")]
14 NotFound = ENOENT,
15 #[error("No such process")]
16 NoSuchProcess = ESRCH,
17 #[error("Interrupted system call")]
18 Interrupted = EINTR,
19 #[error("Input/output error")]
20 IoError = EIO,
21 #[error("Argument list too long")]
22 ArgumentListTooLong = E2BIG,
23 #[error("Exec format error")]
24 ExecFormatError = ENOEXEC,
25 #[error("Bad file descriptor")]
26 BadHandle = EBADF,
27 #[error("No child processes")]
28 NoChildren = ECHILD,
29 #[error("Resource temporarily unavailable")]
30 Again = EAGAIN,
31 #[error("Cannot allocate memory")]
32 OutOfMemory = ENOMEM,
33 #[error("Permission denied")]
34 AccessDenied = EACCES,
35 #[error("Bad address")]
36 Fault = EFAULT,
37 #[error("File exists")]
38 AlreadyExists = EEXIST,
39 #[error("Not a directory")]
40 NotADirectory = ENOTDIR,
41 #[error("Is a directory")]
42 IsADirectory = EISDIR,
43 #[error("Invalid argument")]
44 InvalidArgument = EINVAL,
45 #[error("Not a typewriter")]
46 NotATty = ENOTTY,
47 #[error("No space left on device")]
48 NoSpace = ENOSPC,
49 #[error("Broken pipe")]
50 Pipe = EPIPE,
51 #[error("Result too large")]
52 RangeError = ERANGE,
53 #[error("File name too long")]
54 NameTooLong = ENAMETOOLONG,
55 #[error("Function not implemented")]
56 NotImplemented = ENOSYS,
57 #[error("Directory not empty")]
58 NotEmpty = ENOTEMPTY,
59 #[error("Too many levels of symbolic links")]
60 SymlinkLoop = ELOOP,
61 #[error("Not supported")]
62 NotSupported = ENOTSUP,
63 #[error("Address already in use")]
64 AddressInUse = EADDRINUSE,
65 #[error("No buffer space available")]
66 QueueFull = ENOBUFS,
67 #[error("Connection timed out")]
68 TimedOut = ETIMEDOUT,
69 #[error("Connection refused")]
70 ConnectionRefused = ECONNREFUSED,
71 #[error("Unknown error (errno={0})")]
72 #[num_enum(catch_all)]
73 Unknown(usize),
74}
75
76impl Error {
77 #[inline]
78 pub fn from_errno(errno: usize) -> Self {
80 Self::try_from(errno).unwrap_or(Error::Unknown(errno))
81 }
82
83 #[inline]
84 pub fn to_errno(&self) -> usize {
86 usize::from(*self)
87 }
88
89 #[inline]
90 pub fn demux(ret: usize) -> core::result::Result<usize, Error> {
92 let ret_s = ret as isize;
94 if ret_s >= -ERRNO_MAX && ret_s < 0 {
95 Err(Error::from_errno((-ret_s) as usize))
96 } else {
97 Ok(ret)
98 }
99 }
100
101 #[inline]
102 pub fn is_retryable(&self) -> bool {
104 matches!(self, Error::Interrupted | Error::Again)
105 }
106
107 #[inline]
108 pub fn name(&self) -> &'static str {
110 match self {
111 Error::PermissionDenied => "EPERM",
112 Error::NotFound => "ENOENT",
113 Error::NoSuchProcess => "ESRCH",
114 Error::Interrupted => "EINTR",
115 Error::IoError => "EIO",
116 Error::ArgumentListTooLong => "E2BIG",
117 Error::ExecFormatError => "ENOEXEC",
118 Error::BadHandle => "EBADF",
119 Error::NoChildren => "ECHILD",
120 Error::Again => "EAGAIN",
121 Error::OutOfMemory => "ENOMEM",
122 Error::AccessDenied => "EACCES",
123 Error::Fault => "EFAULT",
124 Error::AlreadyExists => "EEXIST",
125 Error::NotADirectory => "ENOTDIR",
126 Error::IsADirectory => "EISDIR",
127 Error::InvalidArgument => "EINVAL",
128 Error::NotATty => "ENOTTY",
129 Error::NoSpace => "ENOSPC",
130 Error::Pipe => "EPIPE",
131 Error::RangeError => "ERANGE",
132 Error::NameTooLong => "ENAMETOOLONG",
133 Error::NotImplemented => "ENOSYS",
134 Error::NotEmpty => "ENOTEMPTY",
135 Error::SymlinkLoop => "ELOOP",
136 Error::NotSupported => "ENOTSUP",
137 Error::AddressInUse => "EADDRINUSE",
138 Error::QueueFull => "ENOBUFS",
139 Error::TimedOut => "ETIMEDOUT",
140 Error::ConnectionRefused => "ECONNREFUSED",
141 Error::Unknown(_) => "E???",
142 }
143 }
144}
145
146pub type Result<T> = core::result::Result<T, Error>;