|
14 | 14 | //! compiling for wasm. That way it's a compile time error for something that's
|
15 | 15 | //! guaranteed to be a runtime error!
|
16 | 16 |
|
| 17 | +use crate::io as std_io; |
| 18 | +use crate::mem; |
| 19 | + |
17 | 20 | #[path = "../unix/alloc.rs"]
|
18 | 21 | pub mod alloc;
|
19 | 22 | pub mod args;
|
@@ -69,12 +72,123 @@ cfg_if::cfg_if! {
|
69 | 72 | mod common;
|
70 | 73 | pub use common::*;
|
71 | 74 |
|
72 |
| -mod helpers; |
73 |
| -// These exports are listed individually to work around Rust's glob import |
74 |
| -// conflict rules. If we glob export `helpers` and `common` together, then |
75 |
| -// the compiler complains about conflicts. |
76 |
| -pub use helpers::abort_internal; |
77 |
| -pub use helpers::decode_error_kind; |
78 |
| -use helpers::err2io; |
79 |
| -pub use helpers::hashmap_random_keys; |
80 |
| -pub use helpers::is_interrupted; |
| 75 | +#[inline] |
| 76 | +pub fn is_interrupted(errno: i32) -> bool { |
| 77 | + errno == wasi::ERRNO_INTR.raw().into() |
| 78 | +} |
| 79 | + |
| 80 | +pub fn decode_error_kind(errno: i32) -> std_io::ErrorKind { |
| 81 | + use std_io::ErrorKind; |
| 82 | + |
| 83 | + let Ok(errno) = u16::try_from(errno) else { |
| 84 | + return ErrorKind::Uncategorized; |
| 85 | + }; |
| 86 | + |
| 87 | + macro_rules! match_errno { |
| 88 | + ($($($errno:ident)|+ => $errkind:ident),*, _ => $wildcard:ident $(,)?) => { |
| 89 | + match errno { |
| 90 | + $(e if $(e == ::wasi::$errno.raw())||+ => ErrorKind::$errkind),*, |
| 91 | + _ => ErrorKind::$wildcard, |
| 92 | + } |
| 93 | + }; |
| 94 | + } |
| 95 | + |
| 96 | + match_errno! { |
| 97 | + ERRNO_2BIG => ArgumentListTooLong, |
| 98 | + ERRNO_ACCES => PermissionDenied, |
| 99 | + ERRNO_ADDRINUSE => AddrInUse, |
| 100 | + ERRNO_ADDRNOTAVAIL => AddrNotAvailable, |
| 101 | + ERRNO_AFNOSUPPORT => Unsupported, |
| 102 | + ERRNO_AGAIN => WouldBlock, |
| 103 | + // ALREADY => "connection already in progress", |
| 104 | + // BADF => "bad file descriptor", |
| 105 | + // BADMSG => "bad message", |
| 106 | + ERRNO_BUSY => ResourceBusy, |
| 107 | + // CANCELED => "operation canceled", |
| 108 | + // CHILD => "no child processes", |
| 109 | + ERRNO_CONNABORTED => ConnectionAborted, |
| 110 | + ERRNO_CONNREFUSED => ConnectionRefused, |
| 111 | + ERRNO_CONNRESET => ConnectionReset, |
| 112 | + ERRNO_DEADLK => Deadlock, |
| 113 | + // DESTADDRREQ => "destination address required", |
| 114 | + ERRNO_DOM => InvalidInput, |
| 115 | + // DQUOT => /* reserved */, |
| 116 | + ERRNO_EXIST => AlreadyExists, |
| 117 | + // FAULT => "bad address", |
| 118 | + ERRNO_FBIG => FileTooLarge, |
| 119 | + ERRNO_HOSTUNREACH => HostUnreachable, |
| 120 | + // IDRM => "identifier removed", |
| 121 | + // ILSEQ => "illegal byte sequence", |
| 122 | + // INPROGRESS => "operation in progress", |
| 123 | + ERRNO_INTR => Interrupted, |
| 124 | + ERRNO_INVAL => InvalidInput, |
| 125 | + ERRNO_IO => Uncategorized, |
| 126 | + // ISCONN => "socket is connected", |
| 127 | + ERRNO_ISDIR => IsADirectory, |
| 128 | + ERRNO_LOOP => FilesystemLoop, |
| 129 | + // MFILE => "file descriptor value too large", |
| 130 | + ERRNO_MLINK => TooManyLinks, |
| 131 | + // MSGSIZE => "message too large", |
| 132 | + // MULTIHOP => /* reserved */, |
| 133 | + ERRNO_NAMETOOLONG => InvalidFilename, |
| 134 | + ERRNO_NETDOWN => NetworkDown, |
| 135 | + // NETRESET => "connection aborted by network", |
| 136 | + ERRNO_NETUNREACH => NetworkUnreachable, |
| 137 | + // NFILE => "too many files open in system", |
| 138 | + // NOBUFS => "no buffer space available", |
| 139 | + ERRNO_NODEV => NotFound, |
| 140 | + ERRNO_NOENT => NotFound, |
| 141 | + // NOEXEC => "executable file format error", |
| 142 | + // NOLCK => "no locks available", |
| 143 | + // NOLINK => /* reserved */, |
| 144 | + ERRNO_NOMEM => OutOfMemory, |
| 145 | + // NOMSG => "no message of the desired type", |
| 146 | + // NOPROTOOPT => "protocol not available", |
| 147 | + ERRNO_NOSPC => StorageFull, |
| 148 | + ERRNO_NOSYS => Unsupported, |
| 149 | + ERRNO_NOTCONN => NotConnected, |
| 150 | + ERRNO_NOTDIR => NotADirectory, |
| 151 | + ERRNO_NOTEMPTY => DirectoryNotEmpty, |
| 152 | + // NOTRECOVERABLE => "state not recoverable", |
| 153 | + // NOTSOCK => "not a socket", |
| 154 | + ERRNO_NOTSUP => Unsupported, |
| 155 | + // NOTTY => "inappropriate I/O control operation", |
| 156 | + ERRNO_NXIO => NotFound, |
| 157 | + // OVERFLOW => "value too large to be stored in data type", |
| 158 | + // OWNERDEAD => "previous owner died", |
| 159 | + ERRNO_PERM => PermissionDenied, |
| 160 | + ERRNO_PIPE => BrokenPipe, |
| 161 | + // PROTO => "protocol error", |
| 162 | + ERRNO_PROTONOSUPPORT => Unsupported, |
| 163 | + // PROTOTYPE => "protocol wrong type for socket", |
| 164 | + // RANGE => "result too large", |
| 165 | + ERRNO_ROFS => ReadOnlyFilesystem, |
| 166 | + ERRNO_SPIPE => NotSeekable, |
| 167 | + ERRNO_SRCH => NotFound, |
| 168 | + // STALE => /* reserved */, |
| 169 | + ERRNO_TIMEDOUT => TimedOut, |
| 170 | + ERRNO_TXTBSY => ResourceBusy, |
| 171 | + ERRNO_XDEV => CrossesDevices, |
| 172 | + ERRNO_NOTCAPABLE => PermissionDenied, |
| 173 | + _ => Uncategorized, |
| 174 | + } |
| 175 | +} |
| 176 | + |
| 177 | +pub fn abort_internal() -> ! { |
| 178 | + unsafe { libc::abort() } |
| 179 | +} |
| 180 | + |
| 181 | +pub fn hashmap_random_keys() -> (u64, u64) { |
| 182 | + let mut ret = (0u64, 0u64); |
| 183 | + unsafe { |
| 184 | + let base = &mut ret as *mut (u64, u64) as *mut u8; |
| 185 | + let len = mem::size_of_val(&ret); |
| 186 | + wasi::random_get(base, len).expect("random_get failure"); |
| 187 | + } |
| 188 | + return ret; |
| 189 | +} |
| 190 | + |
| 191 | +#[inline] |
| 192 | +fn err2io(err: wasi::Errno) -> std_io::Error { |
| 193 | + std_io::Error::from_raw_os_error(err.raw().into()) |
| 194 | +} |
0 commit comments