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