]> git.proxmox.com Git - rustc.git/blob - vendor/wasi/src/wasi_unstable/mod.rs
New upstream version 1.40.0+dfsg1
[rustc.git] / vendor / wasi / src / wasi_unstable / mod.rs
1 //! This module declares the Rust bindings to the `wasi_unstable` API.
2 //!
3 //! The raw bindings are in the `raw` submodule. They use raw pointers and
4 //! are unsafe. In the the top-level module, raw pointer-length pairs are
5 //! replaced by Rust slice types, output parameters are converted to normal
6 //! return values, names are translated to be more Rust-idiomatic, and the
7 //! functions are safe.
8 //!
9 //! TODO: Not all functions are covered yet; implement the rest of the API.
10
11 pub mod raw;
12
13 use core::ffi::c_void;
14 use core::mem::MaybeUninit;
15 use core::num::NonZeroU16;
16 use raw::*;
17
18 pub type Advice = __wasi_advice_t;
19 pub type ClockId = __wasi_clockid_t;
20 pub type Device = __wasi_device_t;
21 pub type DirCookie = __wasi_dircookie_t;
22 pub type Errno = __wasi_errno_t;
23 pub type Error = NonZeroU16;
24 pub type EventRwFlags = __wasi_eventrwflags_t;
25 pub type EventType = __wasi_eventtype_t;
26 pub type ExitCode = __wasi_exitcode_t;
27 pub type Fd = __wasi_fd_t;
28 pub type FdFlags = __wasi_fdflags_t;
29 pub type FileDelta = __wasi_filedelta_t;
30 pub type FileSize = __wasi_filesize_t;
31 pub type FileType = __wasi_filetype_t;
32 pub type FstFlags = __wasi_fstflags_t;
33 pub type Inode = __wasi_inode_t;
34 pub type LinkCount = __wasi_linkcount_t;
35 pub type LookupFlags = __wasi_lookupflags_t;
36 pub type OFlags = __wasi_oflags_t;
37 pub type PreopenType = __wasi_preopentype_t;
38 pub type RiFlags = __wasi_riflags_t;
39 pub type Rights = __wasi_rights_t;
40 pub type RoFlags = __wasi_roflags_t;
41 pub type SdFlags = __wasi_sdflags_t;
42 pub type SiFlags = __wasi_siflags_t;
43 pub type Signal = __wasi_signal_t;
44 pub type SubclockFlags = __wasi_subclockflags_t;
45 pub type Timestamp = __wasi_timestamp_t;
46 pub type Userdata = __wasi_userdata_t;
47 pub type Whence = __wasi_whence_t;
48 pub type Dirent = __wasi_dirent_t;
49 pub type FdStat = __wasi_fdstat_t;
50 pub type FileStat = __wasi_filestat_t;
51 pub type CIoVec = __wasi_ciovec_t;
52 pub type IoVec = __wasi_iovec_t;
53 pub type Subscription = __wasi_subscription_t;
54 pub type Event = __wasi_event_t;
55 pub type Prestat = __wasi_prestat_t;
56
57 // Assert that `__WASI_ESUCCESS` equals to 0
58 const _ASSERT1: [(); 0] = [(); __WASI_ESUCCESS as usize];
59
60 pub const ADVICE_NORMAL: Advice = __WASI_ADVICE_NORMAL;
61 pub const ADVICE_SEQUENTIAL: Advice = __WASI_ADVICE_SEQUENTIAL;
62 pub const ADVICE_RANDOM: Advice = __WASI_ADVICE_RANDOM;
63 pub const ADVICE_WILLNEED: Advice = __WASI_ADVICE_WILLNEED;
64 pub const ADVICE_DONTNEED: Advice = __WASI_ADVICE_DONTNEED;
65 pub const ADVICE_NOREUSE: Advice = __WASI_ADVICE_NOREUSE;
66 pub const CLOCK_REALTIME: ClockId = __WASI_CLOCK_REALTIME;
67 pub const CLOCK_MONOTONIC: ClockId = __WASI_CLOCK_MONOTONIC;
68 pub const CLOCK_PROCESS_CPUTIME_ID: ClockId = __WASI_CLOCK_PROCESS_CPUTIME_ID;
69 pub const CLOCK_THREAD_CPUTIME_ID: ClockId = __WASI_CLOCK_THREAD_CPUTIME_ID;
70 pub const DIRCOOKIE_START: DirCookie = __WASI_DIRCOOKIE_START;
71
72 pub const STDIN_FD: Fd = __WASI_STDIN_FD;
73 pub const STDOUT_FD: Fd = __WASI_STDOUT_FD;
74 pub const STDERR_FD: Fd = __WASI_STDERR_FD;
75
76 macro_rules! errno_set {
77 {$($safe_const:ident = $raw_const:ident;)*} => {
78 $(
79 pub const $safe_const: Error = unsafe {
80 NonZeroU16::new_unchecked($raw_const)
81 };
82 )*
83 };
84 }
85
86 errno_set! {
87 E2BIG = __WASI_E2BIG;
88 EACCES = __WASI_EACCES;
89 EADDRINUSE = __WASI_EADDRINUSE;
90 EADDRNOTAVAIL = __WASI_EADDRNOTAVAIL;
91 EAFNOSUPPORT = __WASI_EAFNOSUPPORT;
92 EAGAIN = __WASI_EAGAIN;
93 EALREADY = __WASI_EALREADY;
94 EBADF = __WASI_EBADF;
95 EBADMSG = __WASI_EBADMSG;
96 EBUSY = __WASI_EBUSY;
97 ECANCELED = __WASI_ECANCELED;
98 ECHILD = __WASI_ECHILD;
99 ECONNABORTED = __WASI_ECONNABORTED;
100 ECONNREFUSED = __WASI_ECONNREFUSED;
101 ECONNRESET = __WASI_ECONNRESET;
102 EDEADLK = __WASI_EDEADLK;
103 EDESTADDRREQ = __WASI_EDESTADDRREQ;
104 EDOM = __WASI_EDOM;
105 EDQUOT = __WASI_EDQUOT;
106 EEXIST = __WASI_EEXIST;
107 EFAULT = __WASI_EFAULT;
108 EFBIG = __WASI_EFBIG;
109 EHOSTUNREACH = __WASI_EHOSTUNREACH;
110 EIDRM = __WASI_EIDRM;
111 EILSEQ = __WASI_EILSEQ;
112 EINPROGRESS = __WASI_EINPROGRESS;
113 EINTR = __WASI_EINTR;
114 EINVAL = __WASI_EINVAL;
115 EIO = __WASI_EIO;
116 EISCONN = __WASI_EISCONN;
117 EISDIR = __WASI_EISDIR;
118 ELOOP = __WASI_ELOOP;
119 EMFILE = __WASI_EMFILE;
120 EMLINK = __WASI_EMLINK;
121 EMSGSIZE = __WASI_EMSGSIZE;
122 EMULTIHOP = __WASI_EMULTIHOP;
123 ENAMETOOLONG = __WASI_ENAMETOOLONG;
124 ENETDOWN = __WASI_ENETDOWN;
125 ENETRESET = __WASI_ENETRESET;
126 ENETUNREACH = __WASI_ENETUNREACH;
127 ENFILE = __WASI_ENFILE;
128 ENOBUFS = __WASI_ENOBUFS;
129 ENODEV = __WASI_ENODEV;
130 ENOENT = __WASI_ENOENT;
131 ENOEXEC = __WASI_ENOEXEC;
132 ENOLCK = __WASI_ENOLCK;
133 ENOLINK = __WASI_ENOLINK;
134 ENOMEM = __WASI_ENOMEM;
135 ENOMSG = __WASI_ENOMSG;
136 ENOPROTOOPT = __WASI_ENOPROTOOPT;
137 ENOSPC = __WASI_ENOSPC;
138 ENOSYS = __WASI_ENOSYS;
139 ENOTCONN = __WASI_ENOTCONN;
140 ENOTDIR = __WASI_ENOTDIR;
141 ENOTEMPTY = __WASI_ENOTEMPTY;
142 ENOTRECOVERABLE = __WASI_ENOTRECOVERABLE;
143 ENOTSOCK = __WASI_ENOTSOCK;
144 ENOTSUP = __WASI_ENOTSUP;
145 ENOTTY = __WASI_ENOTTY;
146 ENXIO = __WASI_ENXIO;
147 EOVERFLOW = __WASI_EOVERFLOW;
148 EOWNERDEAD = __WASI_EOWNERDEAD;
149 EPERM = __WASI_EPERM;
150 EPIPE = __WASI_EPIPE;
151 EPROTO = __WASI_EPROTO;
152 EPROTONOSUPPORT = __WASI_EPROTONOSUPPORT;
153 EPROTOTYPE = __WASI_EPROTOTYPE;
154 ERANGE = __WASI_ERANGE;
155 EROFS = __WASI_EROFS;
156 ESPIPE = __WASI_ESPIPE;
157 ESRCH = __WASI_ESRCH;
158 ESTALE = __WASI_ESTALE;
159 ETIMEDOUT = __WASI_ETIMEDOUT;
160 ETXTBSY = __WASI_ETXTBSY;
161 EXDEV = __WASI_EXDEV;
162 ENOTCAPABLE = __WASI_ENOTCAPABLE;
163 }
164
165 pub const EVENT_FD_READWRITE_HANGUP: EventRwFlags = __WASI_EVENT_FD_READWRITE_HANGUP;
166 pub const EVENTTYPE_CLOCK: EventType = __WASI_EVENTTYPE_CLOCK;
167 pub const EVENTTYPE_FD_READ: EventType = __WASI_EVENTTYPE_FD_READ;
168 pub const EVENTTYPE_FD_WRITE: EventType = __WASI_EVENTTYPE_FD_WRITE;
169 pub const FDFLAG_APPEND: FdFlags = __WASI_FDFLAG_APPEND;
170 pub const FDFLAG_DSYNC: FdFlags = __WASI_FDFLAG_DSYNC;
171 pub const FDFLAG_NONBLOCK: FdFlags = __WASI_FDFLAG_NONBLOCK;
172 pub const FDFLAG_RSYNC: FdFlags = __WASI_FDFLAG_RSYNC;
173 pub const FDFLAG_SYNC: FdFlags = __WASI_FDFLAG_SYNC;
174 pub const FILETYPE_UNKNOWN: FileType = __WASI_FILETYPE_UNKNOWN;
175 pub const FILETYPE_BLOCK_DEVICE: FileType = __WASI_FILETYPE_BLOCK_DEVICE;
176 pub const FILETYPE_CHARACTER_DEVICE: FileType = __WASI_FILETYPE_CHARACTER_DEVICE;
177 pub const FILETYPE_DIRECTORY: FileType = __WASI_FILETYPE_DIRECTORY;
178 pub const FILETYPE_REGULAR_FILE: FileType = __WASI_FILETYPE_REGULAR_FILE;
179 pub const FILETYPE_SOCKET_DGRAM: FileType = __WASI_FILETYPE_SOCKET_DGRAM;
180 pub const FILETYPE_SOCKET_STREAM: FileType = __WASI_FILETYPE_SOCKET_STREAM;
181 pub const FILETYPE_SYMBOLIC_LINK: FileType = __WASI_FILETYPE_SYMBOLIC_LINK;
182 pub const FILESTAT_SET_ATIM: FstFlags = __WASI_FILESTAT_SET_ATIM;
183 pub const FILESTAT_SET_ATIM_NOW: FstFlags = __WASI_FILESTAT_SET_ATIM_NOW;
184 pub const FILESTAT_SET_MTIM: FstFlags = __WASI_FILESTAT_SET_MTIM;
185 pub const FILESTAT_SET_MTIM_NOW: FstFlags = __WASI_FILESTAT_SET_MTIM_NOW;
186 pub const LOOKUP_SYMLINK_FOLLOW: LookupFlags = __WASI_LOOKUP_SYMLINK_FOLLOW;
187 pub const O_CREAT: OFlags = __WASI_O_CREAT;
188 pub const O_DIRECTORY: OFlags = __WASI_O_DIRECTORY;
189 pub const O_EXCL: OFlags = __WASI_O_EXCL;
190 pub const O_TRUNC: OFlags = __WASI_O_TRUNC;
191 pub const PREOPENTYPE_DIR: PreopenType = __WASI_PREOPENTYPE_DIR;
192 pub const SOCK_RECV_PEEK: RiFlags = __WASI_SOCK_RECV_PEEK;
193 pub const SOCK_RECV_WAITALL: RiFlags = __WASI_SOCK_RECV_WAITALL;
194 pub const RIGHT_FD_DATASYNC: Rights = __WASI_RIGHT_FD_DATASYNC;
195 pub const RIGHT_FD_READ: Rights = __WASI_RIGHT_FD_READ;
196 pub const RIGHT_FD_SEEK: Rights = __WASI_RIGHT_FD_SEEK;
197 pub const RIGHT_FD_FDSTAT_SET_FLAGS: Rights = __WASI_RIGHT_FD_FDSTAT_SET_FLAGS;
198 pub const RIGHT_FD_SYNC: Rights = __WASI_RIGHT_FD_SYNC;
199 pub const RIGHT_FD_TELL: Rights = __WASI_RIGHT_FD_TELL;
200 pub const RIGHT_FD_WRITE: Rights = __WASI_RIGHT_FD_WRITE;
201 pub const RIGHT_FD_ADVISE: Rights = __WASI_RIGHT_FD_ADVISE;
202 pub const RIGHT_FD_ALLOCATE: Rights = __WASI_RIGHT_FD_ALLOCATE;
203 pub const RIGHT_PATH_CREATE_DIRECTORY: Rights = __WASI_RIGHT_PATH_CREATE_DIRECTORY;
204 pub const RIGHT_PATH_CREATE_FILE: Rights = __WASI_RIGHT_PATH_CREATE_FILE;
205 pub const RIGHT_PATH_LINK_SOURCE: Rights = __WASI_RIGHT_PATH_LINK_SOURCE;
206 pub const RIGHT_PATH_LINK_TARGET: Rights = __WASI_RIGHT_PATH_LINK_TARGET;
207 pub const RIGHT_PATH_OPEN: Rights = __WASI_RIGHT_PATH_OPEN;
208 pub const RIGHT_FD_READDIR: Rights = __WASI_RIGHT_FD_READDIR;
209 pub const RIGHT_PATH_READLINK: Rights = __WASI_RIGHT_PATH_READLINK;
210 pub const RIGHT_PATH_RENAME_SOURCE: Rights = __WASI_RIGHT_PATH_RENAME_SOURCE;
211 pub const RIGHT_PATH_RENAME_TARGET: Rights = __WASI_RIGHT_PATH_RENAME_TARGET;
212 pub const RIGHT_PATH_FILESTAT_GET: Rights = __WASI_RIGHT_PATH_FILESTAT_GET;
213 pub const RIGHT_PATH_FILESTAT_SET_SIZE: Rights = __WASI_RIGHT_PATH_FILESTAT_SET_SIZE;
214 pub const RIGHT_PATH_FILESTAT_SET_TIMES: Rights = __WASI_RIGHT_PATH_FILESTAT_SET_TIMES;
215 pub const RIGHT_FD_FILESTAT_GET: Rights = __WASI_RIGHT_FD_FILESTAT_GET;
216 pub const RIGHT_FD_FILESTAT_SET_SIZE: Rights = __WASI_RIGHT_FD_FILESTAT_SET_SIZE;
217 pub const RIGHT_FD_FILESTAT_SET_TIMES: Rights = __WASI_RIGHT_FD_FILESTAT_SET_TIMES;
218 pub const RIGHT_PATH_SYMLINK: Rights = __WASI_RIGHT_PATH_SYMLINK;
219 pub const RIGHT_PATH_REMOVE_DIRECTORY: Rights = __WASI_RIGHT_PATH_REMOVE_DIRECTORY;
220 pub const RIGHT_PATH_UNLINK_FILE: Rights = __WASI_RIGHT_PATH_UNLINK_FILE;
221 pub const RIGHT_POLL_FD_READWRITE: Rights = __WASI_RIGHT_POLL_FD_READWRITE;
222 pub const RIGHT_SOCK_SHUTDOWN: Rights = __WASI_RIGHT_SOCK_SHUTDOWN;
223 pub const SOCK_RECV_DATA_TRUNCATED: RoFlags = __WASI_SOCK_RECV_DATA_TRUNCATED;
224 pub const SHUT_RD: SdFlags = __WASI_SHUT_RD;
225 pub const SHUT_WR: SdFlags = __WASI_SHUT_WR;
226 pub const SIGHUP: Signal = __WASI_SIGHUP;
227 pub const SIGINT: Signal = __WASI_SIGINT;
228 pub const SIGQUIT: Signal = __WASI_SIGQUIT;
229 pub const SIGILL: Signal = __WASI_SIGILL;
230 pub const SIGTRAP: Signal = __WASI_SIGTRAP;
231 pub const SIGABRT: Signal = __WASI_SIGABRT;
232 pub const SIGBUS: Signal = __WASI_SIGBUS;
233 pub const SIGFPE: Signal = __WASI_SIGFPE;
234 pub const SIGKILL: Signal = __WASI_SIGKILL;
235 pub const SIGUSR1: Signal = __WASI_SIGUSR1;
236 pub const SIGSEGV: Signal = __WASI_SIGSEGV;
237 pub const SIGUSR2: Signal = __WASI_SIGUSR2;
238 pub const SIGPIPE: Signal = __WASI_SIGPIPE;
239 pub const SIGALRM: Signal = __WASI_SIGALRM;
240 pub const SIGTERM: Signal = __WASI_SIGTERM;
241 pub const SIGCHLD: Signal = __WASI_SIGCHLD;
242 pub const SIGCONT: Signal = __WASI_SIGCONT;
243 pub const SIGSTOP: Signal = __WASI_SIGSTOP;
244 pub const SIGTSTP: Signal = __WASI_SIGTSTP;
245 pub const SIGTTIN: Signal = __WASI_SIGTTIN;
246 pub const SIGTTOU: Signal = __WASI_SIGTTOU;
247 pub const SIGURG: Signal = __WASI_SIGURG;
248 pub const SIGXCPU: Signal = __WASI_SIGXCPU;
249 pub const SIGXFSZ: Signal = __WASI_SIGXFSZ;
250 pub const SIGVTALRM: Signal = __WASI_SIGVTALRM;
251 pub const SIGPROF: Signal = __WASI_SIGPROF;
252 pub const SIGWINCH: Signal = __WASI_SIGWINCH;
253 pub const SIGPOLL: Signal = __WASI_SIGPOLL;
254 pub const SIGPWR: Signal = __WASI_SIGPWR;
255 pub const SIGSYS: Signal = __WASI_SIGSYS;
256 pub const SUBSCRIPTION_CLOCK_ABSTIME: SubclockFlags = __WASI_SUBSCRIPTION_CLOCK_ABSTIME;
257 pub const WHENCE_CUR: Whence = __WASI_WHENCE_CUR;
258 pub const WHENCE_END: Whence = __WASI_WHENCE_END;
259 pub const WHENCE_SET: Whence = __WASI_WHENCE_SET;
260
261 macro_rules! wrap0 {
262 {$f:expr} => {
263 if let Some(code) = NonZeroU16::new($f) {
264 Err(code)
265 } else {
266 Ok(())
267 }
268 };
269 }
270
271 macro_rules! wrap {
272 {$f:ident($($args:expr),* $(,)?)} => {
273 let mut t = MaybeUninit::uninit();
274 let r = $f($($args,)* t.as_mut_ptr());
275 if let Some(code) = NonZeroU16::new(r) {
276 Err(code)
277 } else {
278 Ok(t.assume_init())
279 }
280 };
281 }
282
283 #[inline]
284 pub fn clock_res_get(clock_id: ClockId) -> Result<Timestamp, Error> {
285 unsafe {
286 wrap! { __wasi_clock_res_get(clock_id) }
287 }
288 }
289
290 #[inline]
291 pub fn clock_time_get(clock_id: ClockId, precision: Timestamp) -> Result<Timestamp, Error> {
292 unsafe {
293 wrap! { __wasi_clock_time_get(clock_id, precision) }
294 }
295 }
296
297 #[inline]
298 pub unsafe fn fd_pread(fd: Fd, iovs: &[IoVec], offset: FileSize) -> Result<usize, Error> {
299 wrap! { __wasi_fd_pread(fd, iovs.as_ptr(), iovs.len(), offset) }
300 }
301
302 #[inline]
303 pub unsafe fn fd_pwrite(fd: Fd, iovs: &[CIoVec], offset: FileSize) -> Result<usize, Error> {
304 wrap! { __wasi_fd_pwrite(fd, iovs.as_ptr(), iovs.len(), offset) }
305 }
306
307 #[inline]
308 pub fn random_get(buf: &mut [u8]) -> Result<(), Error> {
309 unsafe {
310 wrap0! { __wasi_random_get(buf.as_mut_ptr() as *mut c_void, buf.len()) }
311 }
312 }
313
314 #[inline]
315 pub unsafe fn fd_close(fd: Fd) -> Result<(), Error> {
316 wrap0! { __wasi_fd_close(fd) }
317 }
318
319 #[inline]
320 pub unsafe fn fd_datasync(fd: Fd) -> Result<(), Error> {
321 wrap0! { __wasi_fd_datasync(fd) }
322 }
323
324 #[inline]
325 pub unsafe fn fd_read(fd: Fd, iovs: &[IoVec]) -> Result<usize, Error> {
326 wrap! { __wasi_fd_read(fd, iovs.as_ptr(), iovs.len()) }
327 }
328
329 #[inline]
330 pub unsafe fn fd_renumber(from: Fd, to: Fd) -> Result<(), Error> {
331 wrap0! { __wasi_fd_renumber(from, to) }
332 }
333
334 #[inline]
335 pub unsafe fn fd_seek(fd: Fd, offset: FileDelta, whence: Whence) -> Result<FileSize, Error> {
336 wrap! { __wasi_fd_seek(fd, offset, whence) }
337 }
338
339 #[inline]
340 pub unsafe fn fd_tell(fd: Fd) -> Result<FileSize, Error> {
341 wrap! { __wasi_fd_tell(fd) }
342 }
343
344 #[inline]
345 pub unsafe fn fd_fdstat_get(fd: Fd) -> Result<FdStat, Error> {
346 wrap! { __wasi_fd_fdstat_get(fd) }
347 }
348
349 #[inline]
350 pub unsafe fn fd_fdstat_set_flags(fd: Fd, flags: FdFlags) -> Result<(), Error> {
351 wrap0! { __wasi_fd_fdstat_set_flags(fd, flags) }
352 }
353
354 #[inline]
355 pub unsafe fn fd_fdstat_set_rights(
356 fd: Fd,
357 fs_rights_base: Rights,
358 fs_rights_inheriting: Rights,
359 ) -> Result<(), Error> {
360 wrap0! { __wasi_fd_fdstat_set_rights(fd, fs_rights_base, fs_rights_inheriting) }
361 }
362
363 #[inline]
364 pub unsafe fn fd_sync(fd: Fd) -> Result<(), Error> {
365 wrap0! { __wasi_fd_sync(fd) }
366 }
367
368 #[inline]
369 pub unsafe fn fd_write(fd: Fd, iovs: &[CIoVec]) -> Result<usize, Error> {
370 wrap! { __wasi_fd_write(fd, iovs.as_ptr(), iovs.len()) }
371 }
372
373 #[inline]
374 pub unsafe fn fd_advise(
375 fd: Fd,
376 offset: FileSize,
377 len: FileSize,
378 advice: Advice,
379 ) -> Result<(), Error> {
380 wrap0! { __wasi_fd_advise(fd, offset, len, advice) }
381 }
382
383 #[inline]
384 pub unsafe fn fd_allocate(fd: Fd, offset: FileSize, len: FileSize) -> Result<(), Error> {
385 wrap0! { __wasi_fd_allocate(fd, offset, len) }
386 }
387
388 #[inline]
389 pub unsafe fn path_create_directory(fd: Fd, path: &[u8]) -> Result<(), Error> {
390 wrap0! { __wasi_path_create_directory(fd, path.as_ptr(), path.len()) }
391 }
392
393 #[inline]
394 pub unsafe fn path_link(
395 old_fd: Fd,
396 old_flags: LookupFlags,
397 old_path: &[u8],
398 new_fd: Fd,
399 new_path: &[u8],
400 ) -> Result<(), Error> {
401 wrap0! {
402 __wasi_path_link(
403 old_fd,
404 old_flags,
405 old_path.as_ptr(),
406 old_path.len(),
407 new_fd,
408 new_path.as_ptr(),
409 new_path.len(),
410 )
411 }
412 }
413
414 #[inline]
415 pub unsafe fn path_open(
416 dirfd: Fd,
417 dirflags: LookupFlags,
418 path: &[u8],
419 oflags: OFlags,
420 fs_rights_base: Rights,
421 fs_rights_inheriting: Rights,
422 fs_flags: FdFlags,
423 ) -> Result<Fd, Error> {
424 wrap! {
425 __wasi_path_open(
426 dirfd,
427 dirflags,
428 path.as_ptr(),
429 path.len(),
430 oflags,
431 fs_rights_base,
432 fs_rights_inheriting,
433 fs_flags,
434 )
435 }
436 }
437
438 #[inline]
439 pub unsafe fn fd_readdir(fd: Fd, buf: &mut [u8], cookie: DirCookie) -> Result<usize, Error> {
440 let ptr = buf.as_mut_ptr() as *mut c_void;
441 wrap! { __wasi_fd_readdir(fd, ptr, buf.len(), cookie) }
442 }
443
444 #[inline]
445 pub unsafe fn path_readlink(fd: Fd, path: &[u8], buf: &mut [u8]) -> Result<usize, Error> {
446 let ptr = buf.as_mut_ptr();
447 wrap! {
448 __wasi_path_readlink(fd, path.as_ptr(), path.len(), ptr, buf.len())
449 }
450 }
451
452 #[inline]
453 pub unsafe fn path_rename(
454 old_fd: Fd,
455 old_path: &[u8],
456 new_fd: Fd,
457 new_path: &[u8],
458 ) -> Result<(), Error> {
459 wrap0! {
460 __wasi_path_rename(
461 old_fd,
462 old_path.as_ptr(),
463 old_path.len(),
464 new_fd,
465 new_path.as_ptr(),
466 new_path.len(),
467 )
468 }
469 }
470
471 #[inline]
472 pub unsafe fn fd_filestat_get(fd: Fd) -> Result<FileStat, Error> {
473 wrap! { __wasi_fd_filestat_get(fd) }
474 }
475
476 #[inline]
477 pub unsafe fn fd_filestat_set_times(
478 fd: Fd,
479 st_atim: Timestamp,
480 st_mtim: Timestamp,
481 fstflags: FstFlags,
482 ) -> Result<(), Error> {
483 wrap0! { __wasi_fd_filestat_set_times(fd, st_atim, st_mtim, fstflags) }
484 }
485
486 #[inline]
487 pub unsafe fn fd_filestat_set_size(fd: Fd, st_size: FileSize) -> Result<(), Error> {
488 wrap0! { __wasi_fd_filestat_set_size(fd, st_size) }
489 }
490
491 #[inline]
492 pub unsafe fn path_filestat_get(
493 fd: Fd,
494 flags: LookupFlags,
495 path: &[u8],
496 ) -> Result<FileStat, Error> {
497 wrap! {
498 __wasi_path_filestat_get(fd, flags, path.as_ptr(), path.len())
499 }
500 }
501
502 #[inline]
503 pub unsafe fn path_filestat_set_times(
504 fd: Fd,
505 flags: LookupFlags,
506 path: &[u8],
507 st_atim: Timestamp,
508 st_mtim: Timestamp,
509 fstflags: FstFlags,
510 ) -> Result<(), Error> {
511 wrap0! {
512 __wasi_path_filestat_set_times(
513 fd,
514 flags,
515 path.as_ptr(),
516 path.len(),
517 st_atim,
518 st_mtim,
519 fstflags,
520 )
521 }
522 }
523
524 #[inline]
525 pub unsafe fn path_symlink(old_path: &[u8], fd: Fd, new_path: &[u8]) -> Result<(), Error> {
526 wrap0! {
527 __wasi_path_symlink(
528 old_path.as_ptr(),
529 old_path.len(),
530 fd,
531 new_path.as_ptr(),
532 new_path.len(),
533 )
534 }
535 }
536
537 #[inline]
538 pub unsafe fn path_unlink_file(fd: Fd, path: &[u8]) -> Result<(), Error> {
539 wrap0! { __wasi_path_unlink_file(fd, path.as_ptr(), path.len()) }
540 }
541
542 #[inline]
543 pub unsafe fn path_remove_directory(fd: Fd, path: &[u8]) -> Result<(), Error> {
544 wrap0! { __wasi_path_remove_directory(fd, path.as_ptr(), path.len()) }
545 }
546
547 #[inline]
548 pub unsafe fn poll_oneoff(in_: &[Subscription], out: &mut [Event]) -> Result<usize, Error> {
549 assert!(out.len() >= in_.len());
550 let ptr = out.as_mut_ptr() as *mut __wasi_event_t;
551 wrap! {
552 __wasi_poll_oneoff(
553 in_.as_ptr(),
554 ptr,
555 in_.len(),
556 )
557 }
558 }
559
560 #[inline]
561 pub fn proc_exit(rval: ExitCode) -> ! {
562 unsafe { __wasi_proc_exit(rval) }
563 }
564
565 #[inline]
566 pub unsafe fn sock_recv(
567 sock: Fd,
568 ri_data: &[IoVec],
569 ri_flags: RiFlags,
570 ) -> Result<(usize, RoFlags), Error> {
571 let mut ro_datalen = MaybeUninit::<usize>::uninit();
572 let mut ro_flags = MaybeUninit::<RoFlags>::uninit();
573 let r = __wasi_sock_recv(
574 sock,
575 ri_data.as_ptr(),
576 ri_data.len(),
577 ri_flags,
578 ro_datalen.as_mut_ptr(),
579 ro_flags.as_mut_ptr(),
580 );
581 if let Some(code) = NonZeroU16::new(r) {
582 Err(code)
583 } else {
584 Ok((ro_datalen.assume_init(), ro_flags.assume_init()))
585 }
586 }
587
588 #[inline]
589 pub unsafe fn sock_send(sock: Fd, si_data: &[CIoVec], si_flags: SiFlags) -> Result<usize, Error> {
590 wrap! { __wasi_sock_send(sock, si_data.as_ptr(), si_data.len(), si_flags) }
591 }
592
593 #[inline]
594 pub unsafe fn sock_shutdown(sock: Fd, how: SdFlags) -> Result<(), Error> {
595 wrap0! { __wasi_sock_shutdown(sock, how) }
596 }
597
598 #[inline]
599 pub fn sched_yield() -> Result<(), Error> {
600 unsafe {
601 wrap0! { __wasi_sched_yield() }
602 }
603 }
604
605 #[inline]
606 pub unsafe fn fd_prestat_get(fd: Fd) -> Result<Prestat, Error> {
607 wrap! { __wasi_fd_prestat_get(fd) }
608 }
609
610 #[inline]
611 pub unsafe fn fd_prestat_dir_name(fd: Fd, path: &mut [u8]) -> Result<(), Error> {
612 wrap0! { __wasi_fd_prestat_dir_name(fd, path.as_mut_ptr(), path.len()) }
613 }
614
615 #[derive(Copy, Clone)]
616 pub struct ArgsSizes {
617 count: usize,
618 buf_len: usize,
619 }
620
621 impl ArgsSizes {
622 #[inline]
623 pub fn get_count(&self) -> usize {
624 self.count
625 }
626 #[inline]
627 pub fn get_buf_len(&self) -> usize {
628 self.buf_len
629 }
630 }
631
632 #[inline]
633 pub fn args_sizes_get() -> Result<ArgsSizes, Error> {
634 let mut res = ArgsSizes {
635 count: 0,
636 buf_len: 0,
637 };
638 let code = unsafe { __wasi_args_sizes_get(&mut res.count, &mut res.buf_len) };
639 if let Some(err) = NonZeroU16::new(code) {
640 return Err(err);
641 }
642 Ok(res)
643 }
644
645 #[cfg(feature = "alloc")]
646 #[inline]
647 pub fn args_get(ars: ArgsSizes, mut process_arg: impl FnMut(&[u8])) -> Result<(), Error> {
648 use alloc::vec;
649
650 // TODO: remove allocations after stabilization of unsized rvalues, see:
651 // https://github.com/rust-lang/rust/issues/48055
652 let mut arg_ptrs = vec![core::ptr::null_mut::<u8>(); ars.count];
653 let mut arg_buf = vec![0u8; ars.buf_len];
654 let ret = unsafe { __wasi_args_get(arg_ptrs.as_mut_ptr(), arg_buf.as_mut_ptr()) };
655 if let Some(err) = NonZeroU16::new(ret) {
656 return Err(err);
657 }
658
659 for ptr in arg_ptrs {
660 for n in 0.. {
661 unsafe {
662 if *ptr.add(n) == 0 {
663 let slice = core::slice::from_raw_parts(ptr, n);
664 process_arg(slice);
665 break;
666 }
667 }
668 }
669 }
670
671 Ok(())
672 }
673
674 #[derive(Copy, Clone)]
675 pub struct EnvironSizes {
676 count: usize,
677 buf_len: usize,
678 }
679
680 impl EnvironSizes {
681 #[inline]
682 pub fn get_count(&self) -> usize {
683 self.count
684 }
685 #[inline]
686 pub fn get_buf_len(&self) -> usize {
687 self.buf_len
688 }
689 }
690
691 #[inline]
692 pub fn environ_sizes_get() -> Result<EnvironSizes, Error> {
693 let mut res = EnvironSizes {
694 count: 0,
695 buf_len: 0,
696 };
697 let code = unsafe { __wasi_environ_sizes_get(&mut res.count, &mut res.buf_len) };
698 if let Some(err) = NonZeroU16::new(code) {
699 return Err(err);
700 }
701 Ok(res)
702 }
703
704 #[cfg(feature = "alloc")]
705 #[inline]
706 pub fn environ_get(
707 es: EnvironSizes,
708 mut process_env: impl FnMut(&[u8], &[u8]),
709 ) -> Result<(), Error> {
710 use alloc::vec;
711
712 // TODO: remove allocations after stabilization of unsized rvalues, see:
713 // https://github.com/rust-lang/rust/issues/48055
714 let mut env_ptrs = vec![core::ptr::null_mut::<u8>(); es.count];
715 let mut env_buf = vec![0u8; es.buf_len];
716 let ret = unsafe { __wasi_environ_get(env_ptrs.as_mut_ptr(), env_buf.as_mut_ptr()) };
717 if let Some(err) = NonZeroU16::new(ret) {
718 return Err(err);
719 }
720
721 for ptr in env_ptrs {
722 let mut key: &[u8] = &[];
723 for n in 0.. {
724 unsafe {
725 match *ptr.add(n) {
726 0 => {
727 let val = core::slice::from_raw_parts(ptr, n);
728 process_env(key, val);
729 break;
730 }
731 b'=' if key.is_empty() => {
732 key = core::slice::from_raw_parts(ptr, n);
733 }
734 _ => {}
735 }
736 }
737 }
738 }
739
740 Ok(())
741 }
742
743 pub fn error_str(err: Error) -> Option<&'static str> {
744 let desc = match err {
745 E2BIG => "Argument list too long",
746 EACCES => "Permission denied",
747 EADDRINUSE => "Address in use",
748 EADDRNOTAVAIL => "Address not available",
749 EAFNOSUPPORT => "Address family not supported by protocol",
750 EAGAIN => "Resource temporarily unavailable",
751 EALREADY => "Operation already in progress",
752 EBADF => "Bad file descriptor",
753 EBADMSG => "Bad message",
754 EBUSY => "Resource busy",
755 ECANCELED => "Operation canceled",
756 ECHILD => "No child process",
757 ECONNABORTED => "Connection aborted",
758 ECONNREFUSED => "Connection refused",
759 ECONNRESET => "Connection reset by peer",
760 EDEADLK => "Resource deadlock would occur",
761 EDESTADDRREQ => "Destination address required",
762 EDOM => "Domain error",
763 EDQUOT => "Quota exceeded",
764 EEXIST => "File exists",
765 EFAULT => "Bad address",
766 EFBIG => "File too large",
767 EHOSTUNREACH => "Host is unreachable",
768 EIDRM => "Identifier removed",
769 EILSEQ => "Illegal byte sequence",
770 EINPROGRESS => "Operation in progress",
771 EINTR => "Interrupted system call",
772 EINVAL => "Invalid argument",
773 EIO => "Remote I/O error",
774 EISCONN => "Socket is connected",
775 EISDIR => "Is a directory",
776 ELOOP => "Symbolic link loop",
777 EMFILE => "No file descriptors available",
778 EMLINK => "Too many links",
779 EMSGSIZE => "Message too large",
780 EMULTIHOP => "Multihop attempted",
781 ENAMETOOLONG => "Filename too long",
782 ENETDOWN => "Network is down",
783 ENETRESET => "Connection reset by network",
784 ENETUNREACH => "Network unreachable",
785 ENFILE => "Too many open files in system",
786 ENOBUFS => "No buffer space available",
787 ENODEV => "No such device",
788 ENOENT => "No such file or directory",
789 ENOEXEC => "Exec format error",
790 ENOLCK => "No locks available",
791 ENOLINK => "Link has been severed",
792 ENOMEM => "Out of memory",
793 ENOMSG => "No message of desired type",
794 ENOPROTOOPT => "Protocol not available",
795 ENOSPC => "No space left on device",
796 ENOSYS => "Function not implemented",
797 ENOTCONN => "Socket not connected",
798 ENOTDIR => "Not a directory",
799 ENOTEMPTY => "Directory not empty",
800 ENOTRECOVERABLE => "State not recoverable",
801 ENOTSOCK => "Not a socket",
802 ENOTSUP => "Not supported",
803 ENOTTY => "Not a tty",
804 ENXIO => "No such device or address",
805 EOVERFLOW => "Value too large for data type",
806 EOWNERDEAD => "Previous owner died",
807 EPERM => "Operation not permitted",
808 EPIPE => "Broken pipe",
809 EPROTO => "Protocol error",
810 EPROTONOSUPPORT => "Protocol not supported",
811 EPROTOTYPE => "Protocol wrong type for socket",
812 ERANGE => "Result not representable",
813 EROFS => "Read-only file system",
814 ESPIPE => "Invalid seek",
815 ESRCH => "No such process",
816 ESTALE => "Stale file handle",
817 ETIMEDOUT => "Operation timed out",
818 ETXTBSY => "Text file busy",
819 EXDEV => "Cross-device link",
820 ENOTCAPABLE => "Capabilities insufficient",
821 _ => return None,
822 };
823 Some(desc)
824 }