1 //! WASI host types. These are types that contain raw pointers and `usize`
2 //! values, and so are platform-specific.
3
4 #![allow(non_camel_case_types)]
5 #![allow(non_snake_case)]
6
7 use crate::old::snapshot_0::wasi::*;
8 use std::{convert::TryInto, io, mem, slice};
9 use wig::witx_host_types;
10
11 witx_host_types!("phases/old/snapshot_0/witx/wasi_unstable.witx");
12
ciovec_to_host(ciovec: &__wasi_ciovec_t) -> io::IoSlice13 pub(crate) unsafe fn ciovec_to_host(ciovec: &__wasi_ciovec_t) -> io::IoSlice {
14 let slice = slice::from_raw_parts(ciovec.buf as *const u8, ciovec.buf_len);
15 io::IoSlice::new(slice)
16 }
17
iovec_to_host_mut(iovec: &mut __wasi_iovec_t) -> io::IoSliceMut18 pub(crate) unsafe fn iovec_to_host_mut(iovec: &mut __wasi_iovec_t) -> io::IoSliceMut {
19 let slice = slice::from_raw_parts_mut(iovec.buf as *mut u8, iovec.buf_len);
20 io::IoSliceMut::new(slice)
21 }
22
23 #[allow(dead_code)] // trouble with sockets
24 #[derive(Clone, Copy, Debug)]
25 #[repr(u8)]
26 pub(crate) enum FileType {
27 Unknown = __WASI_FILETYPE_UNKNOWN,
28 BlockDevice = __WASI_FILETYPE_BLOCK_DEVICE,
29 CharacterDevice = __WASI_FILETYPE_CHARACTER_DEVICE,
30 Directory = __WASI_FILETYPE_DIRECTORY,
31 RegularFile = __WASI_FILETYPE_REGULAR_FILE,
32 SocketDgram = __WASI_FILETYPE_SOCKET_DGRAM,
33 SocketStream = __WASI_FILETYPE_SOCKET_STREAM,
34 Symlink = __WASI_FILETYPE_SYMBOLIC_LINK,
35 }
36
37 impl FileType {
to_wasi(&self) -> __wasi_filetype_t38 pub(crate) fn to_wasi(&self) -> __wasi_filetype_t {
39 *self as __wasi_filetype_t
40 }
41 }
42
43 #[derive(Debug, Clone)]
44 pub(crate) struct Dirent {
45 pub name: String,
46 pub ftype: FileType,
47 pub ino: u64,
48 pub cookie: __wasi_dircookie_t,
49 }
50
51 impl Dirent {
52 /// Serialize the directory entry to the format define by `__wasi_fd_readdir`,
53 /// so that the serialized entries can be concatenated by the implementation.
to_wasi_raw(&self) -> WasiResult<Vec<u8>>54 pub fn to_wasi_raw(&self) -> WasiResult<Vec<u8>> {
55 let name = self.name.as_bytes();
56 let namlen = name.len();
57 let dirent_size = mem::size_of::<__wasi_dirent_t>();
58 let offset = dirent_size
59 .checked_add(namlen)
60 .ok_or(WasiError::EOVERFLOW)?;
61
62 let mut raw = Vec::<u8>::with_capacity(offset);
63 raw.resize(offset, 0);
64
65 let sys_dirent = raw.as_mut_ptr() as *mut __wasi_dirent_t;
66 unsafe {
67 sys_dirent.write_unaligned(__wasi_dirent_t {
68 d_namlen: namlen.try_into()?,
69 d_ino: self.ino,
70 d_next: self.cookie,
71 d_type: self.ftype.to_wasi(),
72 });
73 }
74
75 let sys_name = unsafe { sys_dirent.offset(1) as *mut u8 };
76 let sys_name = unsafe { slice::from_raw_parts_mut(sys_name, namlen) };
77 sys_name.copy_from_slice(&name);
78
79 Ok(raw)
80 }
81 }
82