1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
|
//! System bindings for the wasm/web platform
//!
//! This module contains the facade (aka platform-specific) implementations of
//! OS level functionality for wasm. Note that this wasm is *not* the emscripten
//! wasm, so we have no runtime here.
//!
//! This is all super highly experimental and not actually intended for
//! wide/production use yet, it's still all in the experimental category. This
//! will likely change over time.
//!
//! Currently all functions here are basically stubs that immediately return
//! errors. The hope is that with a portability lint we can turn actually just
//! remove all this and just omit parts of the standard library if we're
//! compiling for wasm. That way it's a compile time error for something that's
//! guaranteed to be a runtime error!
use crate::io as std_io;
use crate::mem;
#[path = "../unix/alloc.rs"]
pub mod alloc;
pub mod args;
#[path = "../unix/cmath.rs"]
pub mod cmath;
pub mod env;
pub mod fd;
pub mod fs;
#[allow(unused)]
#[path = "../wasm/atomics/futex.rs"]
pub mod futex;
pub mod io;
pub mod net;
pub mod os;
#[path = "../unix/os_str.rs"]
pub mod os_str;
#[path = "../unix/path.rs"]
pub mod path;
#[path = "../unsupported/pipe.rs"]
pub mod pipe;
#[path = "../unsupported/process.rs"]
pub mod process;
pub mod stdio;
pub mod thread;
#[path = "../unsupported/thread_local_dtor.rs"]
pub mod thread_local_dtor;
#[path = "../unsupported/thread_local_key.rs"]
pub mod thread_local_key;
pub mod time;
cfg_if::cfg_if! {
if #[cfg(target_feature = "atomics")] {
#[path = "../unix/locks"]
pub mod locks {
#![allow(unsafe_op_in_unsafe_fn)]
mod futex_condvar;
mod futex_mutex;
mod futex_rwlock;
pub(crate) use futex_condvar::Condvar;
pub(crate) use futex_mutex::Mutex;
pub(crate) use futex_rwlock::RwLock;
}
} else {
#[path = "../unsupported/locks/mod.rs"]
pub mod locks;
#[path = "../unsupported/once.rs"]
pub mod once;
#[path = "../unsupported/thread_parking.rs"]
pub mod thread_parking;
}
}
#[path = "../unsupported/common.rs"]
#[deny(unsafe_op_in_unsafe_fn)]
#[allow(unused)]
mod common;
pub use common::*;
#[inline]
pub fn is_interrupted(errno: i32) -> bool {
errno == wasi::ERRNO_INTR.raw().into()
}
pub fn decode_error_kind(errno: i32) -> std_io::ErrorKind {
use std_io::ErrorKind;
let Ok(errno) = u16::try_from(errno) else {
return ErrorKind::Uncategorized;
};
macro_rules! match_errno {
($($($errno:ident)|+ => $errkind:ident),*, _ => $wildcard:ident $(,)?) => {
match errno {
$(e if $(e == ::wasi::$errno.raw())||+ => ErrorKind::$errkind),*,
_ => ErrorKind::$wildcard,
}
};
}
match_errno! {
ERRNO_2BIG => ArgumentListTooLong,
ERRNO_ACCES => PermissionDenied,
ERRNO_ADDRINUSE => AddrInUse,
ERRNO_ADDRNOTAVAIL => AddrNotAvailable,
ERRNO_AFNOSUPPORT => Unsupported,
ERRNO_AGAIN => WouldBlock,
// ALREADY => "connection already in progress",
// BADF => "bad file descriptor",
// BADMSG => "bad message",
ERRNO_BUSY => ResourceBusy,
// CANCELED => "operation canceled",
// CHILD => "no child processes",
ERRNO_CONNABORTED => ConnectionAborted,
ERRNO_CONNREFUSED => ConnectionRefused,
ERRNO_CONNRESET => ConnectionReset,
ERRNO_DEADLK => Deadlock,
// DESTADDRREQ => "destination address required",
ERRNO_DOM => InvalidInput,
// DQUOT => /* reserved */,
ERRNO_EXIST => AlreadyExists,
// FAULT => "bad address",
ERRNO_FBIG => FileTooLarge,
ERRNO_HOSTUNREACH => HostUnreachable,
// IDRM => "identifier removed",
// ILSEQ => "illegal byte sequence",
// INPROGRESS => "operation in progress",
ERRNO_INTR => Interrupted,
ERRNO_INVAL => InvalidInput,
ERRNO_IO => Uncategorized,
// ISCONN => "socket is connected",
ERRNO_ISDIR => IsADirectory,
ERRNO_LOOP => FilesystemLoop,
// MFILE => "file descriptor value too large",
ERRNO_MLINK => TooManyLinks,
// MSGSIZE => "message too large",
// MULTIHOP => /* reserved */,
ERRNO_NAMETOOLONG => InvalidFilename,
ERRNO_NETDOWN => NetworkDown,
// NETRESET => "connection aborted by network",
ERRNO_NETUNREACH => NetworkUnreachable,
// NFILE => "too many files open in system",
// NOBUFS => "no buffer space available",
ERRNO_NODEV => NotFound,
ERRNO_NOENT => NotFound,
// NOEXEC => "executable file format error",
// NOLCK => "no locks available",
// NOLINK => /* reserved */,
ERRNO_NOMEM => OutOfMemory,
// NOMSG => "no message of the desired type",
// NOPROTOOPT => "protocol not available",
ERRNO_NOSPC => StorageFull,
ERRNO_NOSYS => Unsupported,
ERRNO_NOTCONN => NotConnected,
ERRNO_NOTDIR => NotADirectory,
ERRNO_NOTEMPTY => DirectoryNotEmpty,
// NOTRECOVERABLE => "state not recoverable",
// NOTSOCK => "not a socket",
ERRNO_NOTSUP => Unsupported,
// NOTTY => "inappropriate I/O control operation",
ERRNO_NXIO => NotFound,
// OVERFLOW => "value too large to be stored in data type",
// OWNERDEAD => "previous owner died",
ERRNO_PERM => PermissionDenied,
ERRNO_PIPE => BrokenPipe,
// PROTO => "protocol error",
ERRNO_PROTONOSUPPORT => Unsupported,
// PROTOTYPE => "protocol wrong type for socket",
// RANGE => "result too large",
ERRNO_ROFS => ReadOnlyFilesystem,
ERRNO_SPIPE => NotSeekable,
ERRNO_SRCH => NotFound,
// STALE => /* reserved */,
ERRNO_TIMEDOUT => TimedOut,
ERRNO_TXTBSY => ResourceBusy,
ERRNO_XDEV => CrossesDevices,
ERRNO_NOTCAPABLE => PermissionDenied,
_ => Uncategorized,
}
}
pub fn abort_internal() -> ! {
unsafe { libc::abort() }
}
pub fn hashmap_random_keys() -> (u64, u64) {
let mut ret = (0u64, 0u64);
unsafe {
let base = &mut ret as *mut (u64, u64) as *mut u8;
let len = mem::size_of_val(&ret);
wasi::random_get(base, len).expect("random_get failure");
}
return ret;
}
#[inline]
fn err2io(err: wasi::Errno) -> std_io::Error {
std_io::Error::from_raw_os_error(err.raw().into())
}
|