Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bytecodealliance
GitHub Repository: bytecodealliance/wasmtime
Path: blob/main/crates/wasi-common/src/snapshots/preview_1/error.rs
2465 views
1
pub use super::types::{Errno, Error};
2
3
pub trait ErrorExt {
4
fn not_found() -> Self;
5
fn too_big() -> Self;
6
fn badf() -> Self;
7
fn exist() -> Self;
8
fn illegal_byte_sequence() -> Self;
9
fn invalid_argument() -> Self;
10
fn io() -> Self;
11
fn name_too_long() -> Self;
12
fn not_dir() -> Self;
13
fn not_supported() -> Self;
14
fn overflow() -> Self;
15
fn range() -> Self;
16
fn seek_pipe() -> Self;
17
fn perm() -> Self;
18
}
19
20
impl ErrorExt for Error {
21
fn not_found() -> Self {
22
Errno::Noent.into()
23
}
24
fn too_big() -> Self {
25
Errno::TooBig.into()
26
}
27
fn badf() -> Self {
28
Errno::Badf.into()
29
}
30
fn exist() -> Self {
31
Errno::Exist.into()
32
}
33
fn illegal_byte_sequence() -> Self {
34
Errno::Ilseq.into()
35
}
36
fn invalid_argument() -> Self {
37
Errno::Inval.into()
38
}
39
fn io() -> Self {
40
Errno::Io.into()
41
}
42
fn name_too_long() -> Self {
43
Errno::Nametoolong.into()
44
}
45
fn not_dir() -> Self {
46
Errno::Notdir.into()
47
}
48
fn not_supported() -> Self {
49
Errno::Notsup.into()
50
}
51
fn overflow() -> Self {
52
Errno::Overflow.into()
53
}
54
fn range() -> Self {
55
Errno::Range.into()
56
}
57
fn seek_pipe() -> Self {
58
Errno::Spipe.into()
59
}
60
fn perm() -> Self {
61
Errno::Perm.into()
62
}
63
}
64
65
#[cfg(unix)]
66
fn from_raw_os_error(err: Option<i32>) -> Option<Error> {
67
use rustix::io::Errno as RustixErrno;
68
if err.is_none() {
69
return None;
70
}
71
Some(match RustixErrno::from_raw_os_error(err.unwrap()) {
72
RustixErrno::AGAIN => Errno::Again.into(),
73
RustixErrno::PIPE => Errno::Pipe.into(),
74
RustixErrno::PERM => Errno::Perm.into(),
75
RustixErrno::NOENT => Errno::Noent.into(),
76
RustixErrno::NOMEM => Errno::Nomem.into(),
77
RustixErrno::TOOBIG => Errno::TooBig.into(),
78
RustixErrno::IO => Errno::Io.into(),
79
RustixErrno::BADF => Errno::Badf.into(),
80
RustixErrno::BUSY => Errno::Busy.into(),
81
RustixErrno::ACCESS => Errno::Acces.into(),
82
RustixErrno::FAULT => Errno::Fault.into(),
83
RustixErrno::NOTDIR => Errno::Notdir.into(),
84
RustixErrno::ISDIR => Errno::Isdir.into(),
85
RustixErrno::INVAL => Errno::Inval.into(),
86
RustixErrno::EXIST => Errno::Exist.into(),
87
RustixErrno::FBIG => Errno::Fbig.into(),
88
RustixErrno::NOSPC => Errno::Nospc.into(),
89
RustixErrno::SPIPE => Errno::Spipe.into(),
90
RustixErrno::MFILE => Errno::Mfile.into(),
91
RustixErrno::MLINK => Errno::Mlink.into(),
92
RustixErrno::NAMETOOLONG => Errno::Nametoolong.into(),
93
RustixErrno::NFILE => Errno::Nfile.into(),
94
RustixErrno::NOTEMPTY => Errno::Notempty.into(),
95
RustixErrno::LOOP => Errno::Loop.into(),
96
RustixErrno::OVERFLOW => Errno::Overflow.into(),
97
RustixErrno::ILSEQ => Errno::Ilseq.into(),
98
RustixErrno::NOTSUP => Errno::Notsup.into(),
99
RustixErrno::ADDRINUSE => Errno::Addrinuse.into(),
100
RustixErrno::CANCELED => Errno::Canceled.into(),
101
RustixErrno::ADDRNOTAVAIL => Errno::Addrnotavail.into(),
102
RustixErrno::AFNOSUPPORT => Errno::Afnosupport.into(),
103
RustixErrno::ALREADY => Errno::Already.into(),
104
RustixErrno::CONNABORTED => Errno::Connaborted.into(),
105
RustixErrno::CONNREFUSED => Errno::Connrefused.into(),
106
RustixErrno::CONNRESET => Errno::Connreset.into(),
107
RustixErrno::DESTADDRREQ => Errno::Destaddrreq.into(),
108
RustixErrno::DQUOT => Errno::Dquot.into(),
109
RustixErrno::HOSTUNREACH => Errno::Hostunreach.into(),
110
RustixErrno::INPROGRESS => Errno::Inprogress.into(),
111
RustixErrno::INTR => Errno::Intr.into(),
112
RustixErrno::ISCONN => Errno::Isconn.into(),
113
RustixErrno::MSGSIZE => Errno::Msgsize.into(),
114
RustixErrno::NETDOWN => Errno::Netdown.into(),
115
RustixErrno::NETRESET => Errno::Netreset.into(),
116
RustixErrno::NETUNREACH => Errno::Netunreach.into(),
117
RustixErrno::NOBUFS => Errno::Nobufs.into(),
118
RustixErrno::NOPROTOOPT => Errno::Noprotoopt.into(),
119
RustixErrno::NOTCONN => Errno::Notconn.into(),
120
RustixErrno::NOTSOCK => Errno::Notsock.into(),
121
RustixErrno::PROTONOSUPPORT => Errno::Protonosupport.into(),
122
RustixErrno::PROTOTYPE => Errno::Prototype.into(),
123
RustixErrno::STALE => Errno::Stale.into(),
124
RustixErrno::TIMEDOUT => Errno::Timedout.into(),
125
126
// On some platforms.into(), these have the same value as other errno values.
127
#[allow(unreachable_patterns, reason = "see comment")]
128
RustixErrno::WOULDBLOCK => Errno::Again.into(),
129
#[allow(unreachable_patterns, reason = "see comment")]
130
RustixErrno::OPNOTSUPP => Errno::Notsup.into(),
131
132
_ => return None,
133
})
134
}
135
#[cfg(windows)]
136
fn from_raw_os_error(raw_os_error: Option<i32>) -> Option<Error> {
137
use windows_sys::Win32::Foundation;
138
use windows_sys::Win32::Networking::WinSock;
139
140
match raw_os_error.map(|code| code as u32) {
141
Some(Foundation::ERROR_BAD_ENVIRONMENT) => return Some(Errno::TooBig.into()),
142
Some(Foundation::ERROR_FILE_NOT_FOUND) => return Some(Errno::Noent.into()),
143
Some(Foundation::ERROR_PATH_NOT_FOUND) => return Some(Errno::Noent.into()),
144
Some(Foundation::ERROR_TOO_MANY_OPEN_FILES) => return Some(Errno::Nfile.into()),
145
Some(Foundation::ERROR_ACCESS_DENIED) => return Some(Errno::Acces.into()),
146
Some(Foundation::ERROR_SHARING_VIOLATION) => return Some(Errno::Acces.into()),
147
Some(Foundation::ERROR_PRIVILEGE_NOT_HELD) => return Some(Errno::Perm.into()),
148
Some(Foundation::ERROR_INVALID_HANDLE) => return Some(Errno::Badf.into()),
149
Some(Foundation::ERROR_INVALID_NAME) => return Some(Errno::Noent.into()),
150
Some(Foundation::ERROR_NOT_ENOUGH_MEMORY) => return Some(Errno::Nomem.into()),
151
Some(Foundation::ERROR_OUTOFMEMORY) => return Some(Errno::Nomem.into()),
152
Some(Foundation::ERROR_DIR_NOT_EMPTY) => return Some(Errno::Notempty.into()),
153
Some(Foundation::ERROR_NOT_READY) => return Some(Errno::Busy.into()),
154
Some(Foundation::ERROR_BUSY) => return Some(Errno::Busy.into()),
155
Some(Foundation::ERROR_NOT_SUPPORTED) => return Some(Errno::Notsup.into()),
156
Some(Foundation::ERROR_FILE_EXISTS) => return Some(Errno::Exist.into()),
157
Some(Foundation::ERROR_BROKEN_PIPE) => return Some(Errno::Pipe.into()),
158
Some(Foundation::ERROR_BUFFER_OVERFLOW) => return Some(Errno::Nametoolong.into()),
159
Some(Foundation::ERROR_NOT_A_REPARSE_POINT) => return Some(Errno::Inval.into()),
160
Some(Foundation::ERROR_NEGATIVE_SEEK) => return Some(Errno::Inval.into()),
161
Some(Foundation::ERROR_DIRECTORY) => return Some(Errno::Notdir.into()),
162
Some(Foundation::ERROR_ALREADY_EXISTS) => return Some(Errno::Exist.into()),
163
Some(Foundation::ERROR_STOPPED_ON_SYMLINK) => return Some(Errno::Loop.into()),
164
Some(Foundation::ERROR_DIRECTORY_NOT_SUPPORTED) => return Some(Errno::Isdir.into()),
165
_ => {}
166
}
167
168
match raw_os_error {
169
Some(WinSock::WSAEWOULDBLOCK) => Some(Errno::Again.into()),
170
Some(WinSock::WSAECANCELLED) => Some(Errno::Canceled.into()),
171
Some(WinSock::WSA_E_CANCELLED) => Some(Errno::Canceled.into()),
172
Some(WinSock::WSAEBADF) => Some(Errno::Badf.into()),
173
Some(WinSock::WSAEFAULT) => Some(Errno::Fault.into()),
174
Some(WinSock::WSAEINVAL) => Some(Errno::Inval.into()),
175
Some(WinSock::WSAEMFILE) => Some(Errno::Mfile.into()),
176
Some(WinSock::WSAENAMETOOLONG) => Some(Errno::Nametoolong.into()),
177
Some(WinSock::WSAENOTEMPTY) => Some(Errno::Notempty.into()),
178
Some(WinSock::WSAELOOP) => Some(Errno::Loop.into()),
179
Some(WinSock::WSAEOPNOTSUPP) => Some(Errno::Notsup.into()),
180
Some(WinSock::WSAEADDRINUSE) => Some(Errno::Addrinuse.into()),
181
Some(WinSock::WSAEACCES) => Some(Errno::Acces.into()),
182
Some(WinSock::WSAEADDRNOTAVAIL) => Some(Errno::Addrnotavail.into()),
183
Some(WinSock::WSAEAFNOSUPPORT) => Some(Errno::Afnosupport.into()),
184
Some(WinSock::WSAEALREADY) => Some(Errno::Already.into()),
185
Some(WinSock::WSAECONNABORTED) => Some(Errno::Connaborted.into()),
186
Some(WinSock::WSAECONNREFUSED) => Some(Errno::Connrefused.into()),
187
Some(WinSock::WSAECONNRESET) => Some(Errno::Connreset.into()),
188
Some(WinSock::WSAEDESTADDRREQ) => Some(Errno::Destaddrreq.into()),
189
Some(WinSock::WSAEDQUOT) => Some(Errno::Dquot.into()),
190
Some(WinSock::WSAEHOSTUNREACH) => Some(Errno::Hostunreach.into()),
191
Some(WinSock::WSAEINPROGRESS) => Some(Errno::Inprogress.into()),
192
Some(WinSock::WSAEINTR) => Some(Errno::Intr.into()),
193
Some(WinSock::WSAEISCONN) => Some(Errno::Isconn.into()),
194
Some(WinSock::WSAEMSGSIZE) => Some(Errno::Msgsize.into()),
195
Some(WinSock::WSAENETDOWN) => Some(Errno::Netdown.into()),
196
Some(WinSock::WSAENETRESET) => Some(Errno::Netreset.into()),
197
Some(WinSock::WSAENETUNREACH) => Some(Errno::Netunreach.into()),
198
Some(WinSock::WSAENOBUFS) => Some(Errno::Nobufs.into()),
199
Some(WinSock::WSAENOPROTOOPT) => Some(Errno::Noprotoopt.into()),
200
Some(WinSock::WSAENOTCONN) => Some(Errno::Notconn.into()),
201
Some(WinSock::WSAENOTSOCK) => Some(Errno::Notsock.into()),
202
Some(WinSock::WSAEPROTONOSUPPORT) => Some(Errno::Protonosupport.into()),
203
Some(WinSock::WSAEPROTOTYPE) => Some(Errno::Prototype.into()),
204
Some(WinSock::WSAESTALE) => Some(Errno::Stale.into()),
205
Some(WinSock::WSAETIMEDOUT) => Some(Errno::Timedout.into()),
206
_ => None,
207
}
208
}
209
210
impl From<std::io::Error> for Error {
211
fn from(err: std::io::Error) -> Error {
212
match from_raw_os_error(err.raw_os_error()) {
213
Some(errno) => errno,
214
None => match err.kind() {
215
std::io::ErrorKind::NotFound => Errno::Noent.into(),
216
std::io::ErrorKind::PermissionDenied => Errno::Perm.into(),
217
std::io::ErrorKind::AlreadyExists => Errno::Exist.into(),
218
std::io::ErrorKind::InvalidInput => Errno::Inval.into(),
219
std::io::ErrorKind::WouldBlock => Errno::Again.into(),
220
_ => Error::trap(anyhow::anyhow!(err).context("Unknown OS error")),
221
},
222
}
223
}
224
}
225
226
impl From<cap_rand::Error> for Error {
227
fn from(err: cap_rand::Error) -> Error {
228
// I picked Error::Io as a 'reasonable default', FIXME dan is this ok?
229
from_raw_os_error(err.raw_os_error()).unwrap_or_else(|| Error::from(Errno::Io))
230
}
231
}
232
233
impl From<wiggle::GuestError> for Error {
234
fn from(err: wiggle::GuestError) -> Error {
235
use wiggle::GuestError::*;
236
match err {
237
InvalidFlagValue { .. } => Errno::Inval.into(),
238
InvalidEnumValue { .. } => Errno::Inval.into(),
239
// As per
240
// https://github.com/WebAssembly/wasi/blob/main/legacy/tools/witx-docs.md#pointers
241
//
242
// > If a misaligned pointer is passed to a function, the function
243
// > shall trap.
244
// >
245
// > If an out-of-bounds pointer is passed to a function and the
246
// > function needs to dereference it, the function shall trap.
247
//
248
// so this turns OOB and misalignment errors into traps.
249
PtrOverflow { .. } | PtrOutOfBounds { .. } | PtrNotAligned { .. } => {
250
Error::trap(err.into())
251
}
252
InvalidUtf8 { .. } => Errno::Ilseq.into(),
253
TryFromIntError { .. } => Errno::Overflow.into(),
254
SliceLengthsDiffer { .. } => Errno::Fault.into(),
255
InFunc { err, .. } => Error::from(*err),
256
}
257
}
258
}
259
260
impl From<std::num::TryFromIntError> for Error {
261
fn from(_err: std::num::TryFromIntError) -> Error {
262
Errno::Overflow.into()
263
}
264
}
265
266