Reorganize host.rs and wasm32.rs. (#151)

* Reorganize host.rs and wasm32.rs.

Reorganize host.rs and wasm32.rs into host.rs, wasi.rs, and wasi32.rs.

Most of the contents of host.rs was not actually host-specific, as most
of the types are fixed-size types like u32 or i64. These types are now
in wasi.rs.

The few types which do have pointer or usize-sized values now remain,
in two versions: host.rs has versions which use actual raw pointers and
usize, and wasi32.rs has versions which use u32 to represent them.

* Fix compilation on BSD

* Fix compilation on Windows

* Fully encapsulate endianness in memory.rs.

This refactors memory.rs to fully encapsulte endianness concerns, so
that outside that file, all values are in host-endian order.

This adds a dependency on the `num` crate, though it's only used for
the `PrimInt` trait, for handling endianness in a generic way.

* Use pub(crate).
This commit is contained in:
Dan Gohman
2019-11-01 14:21:32 -07:00
committed by GitHub
parent 5f5f31beab
commit a9e3487566
37 changed files with 2010 additions and 2910 deletions

View File

@@ -28,6 +28,7 @@ cfg-if = "0.1.9"
log = "0.4" log = "0.4"
filetime = "0.2.7" filetime = "0.2.7"
lazy_static = "1.4.0" lazy_static = "1.4.0"
num = { version = "0.2.0", default-features = false }
[target.'cfg(unix)'.dependencies] [target.'cfg(unix)'.dependencies]
nix = "0.15" nix = "0.15"

View File

@@ -1,6 +1,6 @@
use crate::fdentry::FdEntry; use crate::fdentry::FdEntry;
use crate::sys::dev_null; use crate::sys::dev_null;
use crate::{host, Error, Result}; use crate::{wasi, Error, Result};
use std::borrow::Borrow; use std::borrow::Borrow;
use std::collections::HashMap; use std::collections::HashMap;
use std::env; use std::env;
@@ -10,7 +10,7 @@ use std::path::{Path, PathBuf};
/// A builder allowing customizable construction of `WasiCtx` instances. /// A builder allowing customizable construction of `WasiCtx` instances.
pub struct WasiCtxBuilder { pub struct WasiCtxBuilder {
fds: HashMap<host::__wasi_fd_t, FdEntry>, fds: HashMap<wasi::__wasi_fd_t, FdEntry>,
preopens: Vec<(PathBuf, File)>, preopens: Vec<(PathBuf, File)>,
args: Vec<CString>, args: Vec<CString>,
env: HashMap<CString, CString>, env: HashMap<CString, CString>,
@@ -162,7 +162,7 @@ impl WasiCtxBuilder {
#[derive(Debug)] #[derive(Debug)]
pub struct WasiCtx { pub struct WasiCtx {
fds: HashMap<host::__wasi_fd_t, FdEntry>, fds: HashMap<wasi::__wasi_fd_t, FdEntry>,
pub(crate) args: Vec<CString>, pub(crate) args: Vec<CString>,
pub(crate) env: Vec<CString>, pub(crate) env: Vec<CString>,
} }
@@ -184,19 +184,19 @@ impl WasiCtx {
} }
/// Check if `WasiCtx` contains the specified raw WASI `fd`. /// Check if `WasiCtx` contains the specified raw WASI `fd`.
pub(crate) unsafe fn contains_fd_entry(&self, fd: host::__wasi_fd_t) -> bool { pub(crate) unsafe fn contains_fd_entry(&self, fd: wasi::__wasi_fd_t) -> bool {
self.fds.contains_key(&fd) self.fds.contains_key(&fd)
} }
/// Get an immutable `FdEntry` corresponding to the specified raw WASI `fd`. /// Get an immutable `FdEntry` corresponding to the specified raw WASI `fd`.
pub(crate) unsafe fn get_fd_entry(&self, fd: host::__wasi_fd_t) -> Result<&FdEntry> { pub(crate) unsafe fn get_fd_entry(&self, fd: wasi::__wasi_fd_t) -> Result<&FdEntry> {
self.fds.get(&fd).ok_or(Error::EBADF) self.fds.get(&fd).ok_or(Error::EBADF)
} }
/// Get a mutable `FdEntry` corresponding to the specified raw WASI `fd`. /// Get a mutable `FdEntry` corresponding to the specified raw WASI `fd`.
pub(crate) unsafe fn get_fd_entry_mut( pub(crate) unsafe fn get_fd_entry_mut(
&mut self, &mut self,
fd: host::__wasi_fd_t, fd: wasi::__wasi_fd_t,
) -> Result<&mut FdEntry> { ) -> Result<&mut FdEntry> {
self.fds.get_mut(&fd).ok_or(Error::EBADF) self.fds.get_mut(&fd).ok_or(Error::EBADF)
} }
@@ -205,7 +205,7 @@ impl WasiCtx {
/// ///
/// The `FdEntry` will automatically get another free raw WASI `fd` assigned. Note that /// The `FdEntry` will automatically get another free raw WASI `fd` assigned. Note that
/// the two subsequent free raw WASI `fd`s do not have to be stored contiguously. /// the two subsequent free raw WASI `fd`s do not have to be stored contiguously.
pub(crate) fn insert_fd_entry(&mut self, fe: FdEntry) -> Result<host::__wasi_fd_t> { pub(crate) fn insert_fd_entry(&mut self, fe: FdEntry) -> Result<wasi::__wasi_fd_t> {
// never insert where stdio handles usually are // never insert where stdio handles usually are
let mut fd = 3; let mut fd = 3;
while self.fds.contains_key(&fd) { while self.fds.contains_key(&fd) {
@@ -223,14 +223,14 @@ impl WasiCtx {
/// object. /// object.
pub(crate) fn insert_fd_entry_at( pub(crate) fn insert_fd_entry_at(
&mut self, &mut self,
fd: host::__wasi_fd_t, fd: wasi::__wasi_fd_t,
fe: FdEntry, fe: FdEntry,
) -> Option<FdEntry> { ) -> Option<FdEntry> {
self.fds.insert(fd, fe) self.fds.insert(fd, fe)
} }
/// Remove `FdEntry` corresponding to the specified raw WASI `fd` from the `WasiCtx` object. /// Remove `FdEntry` corresponding to the specified raw WASI `fd` from the `WasiCtx` object.
pub(crate) fn remove_fd_entry(&mut self, fd: host::__wasi_fd_t) -> Result<FdEntry> { pub(crate) fn remove_fd_entry(&mut self, fd: wasi::__wasi_fd_t) -> Result<FdEntry> {
self.fds.remove(&fd).ok_or(Error::EBADF) self.fds.remove(&fd).ok_or(Error::EBADF)
} }
} }

View File

@@ -1,6 +1,6 @@
// Due to https://github.com/rust-lang/rust/issues/64247 // Due to https://github.com/rust-lang/rust/issues/64247
#![allow(clippy::use_self)] #![allow(clippy::use_self)]
use crate::host; use crate::wasi;
use failure::Fail; use failure::Fail;
use std::convert::Infallible; use std::convert::Infallible;
use std::fmt; use std::fmt;
@@ -9,88 +9,88 @@ use std::num::TryFromIntError;
#[derive(Clone, Copy, Debug, Fail, Eq, PartialEq)] #[derive(Clone, Copy, Debug, Fail, Eq, PartialEq)]
#[repr(u16)] #[repr(u16)]
pub enum WasiError { pub enum WasiError {
ESUCCESS = host::__WASI_ESUCCESS, ESUCCESS = wasi::__WASI_ESUCCESS,
E2BIG = host::__WASI_E2BIG, E2BIG = wasi::__WASI_E2BIG,
EACCES = host::__WASI_EACCES, EACCES = wasi::__WASI_EACCES,
EADDRINUSE = host::__WASI_EADDRINUSE, EADDRINUSE = wasi::__WASI_EADDRINUSE,
EADDRNOTAVAIL = host::__WASI_EADDRNOTAVAIL, EADDRNOTAVAIL = wasi::__WASI_EADDRNOTAVAIL,
EAFNOSUPPORT = host::__WASI_EAFNOSUPPORT, EAFNOSUPPORT = wasi::__WASI_EAFNOSUPPORT,
EAGAIN = host::__WASI_EAGAIN, EAGAIN = wasi::__WASI_EAGAIN,
EALREADY = host::__WASI_EALREADY, EALREADY = wasi::__WASI_EALREADY,
EBADF = host::__WASI_EBADF, EBADF = wasi::__WASI_EBADF,
EBADMSG = host::__WASI_EBADMSG, EBADMSG = wasi::__WASI_EBADMSG,
EBUSY = host::__WASI_EBUSY, EBUSY = wasi::__WASI_EBUSY,
ECANCELED = host::__WASI_ECANCELED, ECANCELED = wasi::__WASI_ECANCELED,
ECHILD = host::__WASI_ECHILD, ECHILD = wasi::__WASI_ECHILD,
ECONNABORTED = host::__WASI_ECONNABORTED, ECONNABORTED = wasi::__WASI_ECONNABORTED,
ECONNREFUSED = host::__WASI_ECONNREFUSED, ECONNREFUSED = wasi::__WASI_ECONNREFUSED,
ECONNRESET = host::__WASI_ECONNRESET, ECONNRESET = wasi::__WASI_ECONNRESET,
EDEADLK = host::__WASI_EDEADLK, EDEADLK = wasi::__WASI_EDEADLK,
EDESTADDRREQ = host::__WASI_EDESTADDRREQ, EDESTADDRREQ = wasi::__WASI_EDESTADDRREQ,
EDOM = host::__WASI_EDOM, EDOM = wasi::__WASI_EDOM,
EDQUOT = host::__WASI_EDQUOT, EDQUOT = wasi::__WASI_EDQUOT,
EEXIST = host::__WASI_EEXIST, EEXIST = wasi::__WASI_EEXIST,
EFAULT = host::__WASI_EFAULT, EFAULT = wasi::__WASI_EFAULT,
EFBIG = host::__WASI_EFBIG, EFBIG = wasi::__WASI_EFBIG,
EHOSTUNREACH = host::__WASI_EHOSTUNREACH, EHOSTUNREACH = wasi::__WASI_EHOSTUNREACH,
EIDRM = host::__WASI_EIDRM, EIDRM = wasi::__WASI_EIDRM,
EILSEQ = host::__WASI_EILSEQ, EILSEQ = wasi::__WASI_EILSEQ,
EINPROGRESS = host::__WASI_EINPROGRESS, EINPROGRESS = wasi::__WASI_EINPROGRESS,
EINTR = host::__WASI_EINTR, EINTR = wasi::__WASI_EINTR,
EINVAL = host::__WASI_EINVAL, EINVAL = wasi::__WASI_EINVAL,
EIO = host::__WASI_EIO, EIO = wasi::__WASI_EIO,
EISCONN = host::__WASI_EISCONN, EISCONN = wasi::__WASI_EISCONN,
EISDIR = host::__WASI_EISDIR, EISDIR = wasi::__WASI_EISDIR,
ELOOP = host::__WASI_ELOOP, ELOOP = wasi::__WASI_ELOOP,
EMFILE = host::__WASI_EMFILE, EMFILE = wasi::__WASI_EMFILE,
EMLINK = host::__WASI_EMLINK, EMLINK = wasi::__WASI_EMLINK,
EMSGSIZE = host::__WASI_EMSGSIZE, EMSGSIZE = wasi::__WASI_EMSGSIZE,
EMULTIHOP = host::__WASI_EMULTIHOP, EMULTIHOP = wasi::__WASI_EMULTIHOP,
ENAMETOOLONG = host::__WASI_ENAMETOOLONG, ENAMETOOLONG = wasi::__WASI_ENAMETOOLONG,
ENETDOWN = host::__WASI_ENETDOWN, ENETDOWN = wasi::__WASI_ENETDOWN,
ENETRESET = host::__WASI_ENETRESET, ENETRESET = wasi::__WASI_ENETRESET,
ENETUNREACH = host::__WASI_ENETUNREACH, ENETUNREACH = wasi::__WASI_ENETUNREACH,
ENFILE = host::__WASI_ENFILE, ENFILE = wasi::__WASI_ENFILE,
ENOBUFS = host::__WASI_ENOBUFS, ENOBUFS = wasi::__WASI_ENOBUFS,
ENODEV = host::__WASI_ENODEV, ENODEV = wasi::__WASI_ENODEV,
ENOENT = host::__WASI_ENOENT, ENOENT = wasi::__WASI_ENOENT,
ENOEXEC = host::__WASI_ENOEXEC, ENOEXEC = wasi::__WASI_ENOEXEC,
ENOLCK = host::__WASI_ENOLCK, ENOLCK = wasi::__WASI_ENOLCK,
ENOLINK = host::__WASI_ENOLINK, ENOLINK = wasi::__WASI_ENOLINK,
ENOMEM = host::__WASI_ENOMEM, ENOMEM = wasi::__WASI_ENOMEM,
ENOMSG = host::__WASI_ENOMSG, ENOMSG = wasi::__WASI_ENOMSG,
ENOPROTOOPT = host::__WASI_ENOPROTOOPT, ENOPROTOOPT = wasi::__WASI_ENOPROTOOPT,
ENOSPC = host::__WASI_ENOSPC, ENOSPC = wasi::__WASI_ENOSPC,
ENOSYS = host::__WASI_ENOSYS, ENOSYS = wasi::__WASI_ENOSYS,
ENOTCONN = host::__WASI_ENOTCONN, ENOTCONN = wasi::__WASI_ENOTCONN,
ENOTDIR = host::__WASI_ENOTDIR, ENOTDIR = wasi::__WASI_ENOTDIR,
ENOTEMPTY = host::__WASI_ENOTEMPTY, ENOTEMPTY = wasi::__WASI_ENOTEMPTY,
ENOTRECOVERABLE = host::__WASI_ENOTRECOVERABLE, ENOTRECOVERABLE = wasi::__WASI_ENOTRECOVERABLE,
ENOTSOCK = host::__WASI_ENOTSOCK, ENOTSOCK = wasi::__WASI_ENOTSOCK,
ENOTSUP = host::__WASI_ENOTSUP, ENOTSUP = wasi::__WASI_ENOTSUP,
ENOTTY = host::__WASI_ENOTTY, ENOTTY = wasi::__WASI_ENOTTY,
ENXIO = host::__WASI_ENXIO, ENXIO = wasi::__WASI_ENXIO,
EOVERFLOW = host::__WASI_EOVERFLOW, EOVERFLOW = wasi::__WASI_EOVERFLOW,
EOWNERDEAD = host::__WASI_EOWNERDEAD, EOWNERDEAD = wasi::__WASI_EOWNERDEAD,
EPERM = host::__WASI_EPERM, EPERM = wasi::__WASI_EPERM,
EPIPE = host::__WASI_EPIPE, EPIPE = wasi::__WASI_EPIPE,
EPROTO = host::__WASI_EPROTO, EPROTO = wasi::__WASI_EPROTO,
EPROTONOSUPPORT = host::__WASI_EPROTONOSUPPORT, EPROTONOSUPPORT = wasi::__WASI_EPROTONOSUPPORT,
EPROTOTYPE = host::__WASI_EPROTOTYPE, EPROTOTYPE = wasi::__WASI_EPROTOTYPE,
ERANGE = host::__WASI_ERANGE, ERANGE = wasi::__WASI_ERANGE,
EROFS = host::__WASI_EROFS, EROFS = wasi::__WASI_EROFS,
ESPIPE = host::__WASI_ESPIPE, ESPIPE = wasi::__WASI_ESPIPE,
ESRCH = host::__WASI_ESRCH, ESRCH = wasi::__WASI_ESRCH,
ESTALE = host::__WASI_ESTALE, ESTALE = wasi::__WASI_ESTALE,
ETIMEDOUT = host::__WASI_ETIMEDOUT, ETIMEDOUT = wasi::__WASI_ETIMEDOUT,
ETXTBSY = host::__WASI_ETXTBSY, ETXTBSY = wasi::__WASI_ETXTBSY,
EXDEV = host::__WASI_EXDEV, EXDEV = wasi::__WASI_EXDEV,
ENOTCAPABLE = host::__WASI_ENOTCAPABLE, ENOTCAPABLE = wasi::__WASI_ENOTCAPABLE,
} }
impl WasiError { impl WasiError {
pub fn as_raw_errno(self) -> host::__wasi_errno_t { pub fn as_raw_errno(self) -> wasi::__wasi_errno_t {
self as host::__wasi_errno_t self as wasi::__wasi_errno_t
} }
} }
@@ -151,7 +151,7 @@ impl From<winx::winerror::WinError> for Error {
} }
impl Error { impl Error {
pub(crate) fn as_wasi_errno(&self) -> host::__wasi_errno_t { pub(crate) fn as_wasi_errno(&self) -> wasi::__wasi_errno_t {
match self { match self {
Self::Wasi(no) => no.as_raw_errno(), Self::Wasi(no) => no.as_raw_errno(),
Self::Io(e) => errno_from_ioerror(e.to_owned()), Self::Io(e) => errno_from_ioerror(e.to_owned()),
@@ -262,12 +262,12 @@ impl fmt::Display for Error {
} }
} }
fn errno_from_ioerror(e: &std::io::Error) -> host::__wasi_errno_t { fn errno_from_ioerror(e: &std::io::Error) -> wasi::__wasi_errno_t {
match e.raw_os_error() { match e.raw_os_error() {
Some(code) => crate::sys::errno_from_host(code), Some(code) => crate::sys::errno_from_host(code),
None => { None => {
log::debug!("Inconvertible OS error: {}", e); log::debug!("Inconvertible OS error: {}", e);
host::__WASI_EIO wasi::__WASI_EIO
} }
} }
} }

View File

@@ -1,5 +1,5 @@
use crate::sys::fdentry_impl::{determine_type_and_access_rights, OsFile}; use crate::sys::fdentry_impl::{determine_type_and_access_rights, OsFile};
use crate::{host, Error, Result}; use crate::{wasi, Error, Result};
use std::path::PathBuf; use std::path::PathBuf;
use std::{fs, io}; use std::{fs, io};
@@ -68,10 +68,10 @@ impl Descriptor {
/// specified, verifying whether the stored `Descriptor` object is valid for the rights specified. /// specified, verifying whether the stored `Descriptor` object is valid for the rights specified.
#[derive(Debug)] #[derive(Debug)]
pub(crate) struct FdEntry { pub(crate) struct FdEntry {
pub(crate) file_type: host::__wasi_filetype_t, pub(crate) file_type: wasi::__wasi_filetype_t,
descriptor: Descriptor, descriptor: Descriptor,
pub(crate) rights_base: host::__wasi_rights_t, pub(crate) rights_base: wasi::__wasi_rights_t,
pub(crate) rights_inheriting: host::__wasi_rights_t, pub(crate) rights_inheriting: wasi::__wasi_rights_t,
pub(crate) preopen_path: Option<PathBuf>, pub(crate) preopen_path: Option<PathBuf>,
// TODO: directories // TODO: directories
} }
@@ -138,8 +138,8 @@ impl FdEntry {
/// `FdEntry::validate_rights` method. If the check fails, `Error::ENOTCAPABLE` is returned. /// `FdEntry::validate_rights` method. If the check fails, `Error::ENOTCAPABLE` is returned.
pub(crate) fn as_descriptor( pub(crate) fn as_descriptor(
&self, &self,
rights_base: host::__wasi_rights_t, rights_base: wasi::__wasi_rights_t,
rights_inheriting: host::__wasi_rights_t, rights_inheriting: wasi::__wasi_rights_t,
) -> Result<&Descriptor> { ) -> Result<&Descriptor> {
self.validate_rights(rights_base, rights_inheriting)?; self.validate_rights(rights_base, rights_inheriting)?;
Ok(&self.descriptor) Ok(&self.descriptor)
@@ -154,8 +154,8 @@ impl FdEntry {
/// `FdEntry::validate_rights` method. If the check fails, `Error::ENOTCAPABLE` is returned. /// `FdEntry::validate_rights` method. If the check fails, `Error::ENOTCAPABLE` is returned.
pub(crate) fn as_descriptor_mut( pub(crate) fn as_descriptor_mut(
&mut self, &mut self,
rights_base: host::__wasi_rights_t, rights_base: wasi::__wasi_rights_t,
rights_inheriting: host::__wasi_rights_t, rights_inheriting: wasi::__wasi_rights_t,
) -> Result<&mut Descriptor> { ) -> Result<&mut Descriptor> {
self.validate_rights(rights_base, rights_inheriting)?; self.validate_rights(rights_base, rights_inheriting)?;
Ok(&mut self.descriptor) Ok(&mut self.descriptor)
@@ -168,8 +168,8 @@ impl FdEntry {
/// Upon unsuccessful check, `Error::ENOTCAPABLE` is returned. /// Upon unsuccessful check, `Error::ENOTCAPABLE` is returned.
fn validate_rights( fn validate_rights(
&self, &self,
rights_base: host::__wasi_rights_t, rights_base: wasi::__wasi_rights_t,
rights_inheriting: host::__wasi_rights_t, rights_inheriting: wasi::__wasi_rights_t,
) -> Result<()> { ) -> Result<()> {
if !self.rights_base & rights_base != 0 || !self.rights_inheriting & rights_inheriting != 0 if !self.rights_base & rights_base != 0 || !self.rights_inheriting & rights_inheriting != 0
{ {

View File

@@ -1,5 +1,5 @@
use crate::fs::{error::wasi_errno_to_io_error, File, OpenOptions, ReadDir}; use crate::fs::{error::wasi_errno_to_io_error, File, OpenOptions, ReadDir};
use crate::{host, hostcalls, WasiCtx}; use crate::{host, hostcalls, wasi, WasiCtx};
#[cfg(unix)] #[cfg(unix)]
use std::os::unix::ffi::OsStrExt; use std::os::unix::ffi::OsStrExt;
use std::{io, path::Path}; use std::{io, path::Path};
@@ -16,12 +16,12 @@ use std::{io, path::Path};
/// don't interoperate well with the capability-oriented security model. /// don't interoperate well with the capability-oriented security model.
pub struct Dir<'ctx> { pub struct Dir<'ctx> {
ctx: &'ctx mut WasiCtx, ctx: &'ctx mut WasiCtx,
fd: host::__wasi_fd_t, fd: wasi::__wasi_fd_t,
} }
impl<'ctx> Dir<'ctx> { impl<'ctx> Dir<'ctx> {
/// Constructs a new instance of `Self` from the given raw WASI file descriptor. /// Constructs a new instance of `Self` from the given raw WASI file descriptor.
pub unsafe fn from_raw_wasi_fd(ctx: &'ctx mut WasiCtx, fd: host::__wasi_fd_t) -> Self { pub unsafe fn from_raw_wasi_fd(ctx: &'ctx mut WasiCtx, fd: wasi::__wasi_fd_t) -> Self {
Self { ctx, fd } Self { ctx, fd }
} }
@@ -52,7 +52,7 @@ impl<'ctx> Dir<'ctx> {
wasi_errno_to_io_error(hostcalls::path_open( wasi_errno_to_io_error(hostcalls::path_open(
self.ctx, self.ctx,
self.fd, self.fd,
host::__WASI_LOOKUP_SYMLINK_FOLLOW, wasi::__WASI_LOOKUP_SYMLINK_FOLLOW,
path.as_os_str().as_bytes(), path.as_os_str().as_bytes(),
path.as_os_str().len(), path.as_os_str().len(),
0, 0,
@@ -98,9 +98,9 @@ impl<'ctx> Dir<'ctx> {
wasi_errno_to_io_error(hostcalls::path_open( wasi_errno_to_io_error(hostcalls::path_open(
self.ctx, self.ctx,
self.fd, self.fd,
host::__WASI_LOOKUP_SYMLINK_FOLLOW, wasi::__WASI_LOOKUP_SYMLINK_FOLLOW,
path.as_os_str().as_bytes(), path.as_os_str().as_bytes(),
host::__WASI_O_DIRECTORY, wasi::__WASI_O_DIRECTORY,
!0, !0,
!0, !0,
0, 0,
@@ -132,10 +132,10 @@ impl<'ctx> Dir<'ctx> {
wasi_errno_to_io_error(hostcalls::path_open( wasi_errno_to_io_error(hostcalls::path_open(
self.ctx, self.ctx,
self.fd, self.fd,
host::__WASI_LOOKUP_SYMLINK_FOLLOW, wasi::__WASI_LOOKUP_SYMLINK_FOLLOW,
path.as_os_str().as_bytes(), path.as_os_str().as_bytes(),
path.as_os_str().len(), path.as_os_str().len(),
host::__WASI_O_CREAT | host::__WASI_O_TRUNC, wasi::__WASI_O_CREAT | wasi::__WASI_O_TRUNC,
!0, !0,
!0, !0,
0, 0,

View File

@@ -1,4 +1,4 @@
use crate::host; use crate::wasi;
use std::io; use std::io;
/// Translate a WASI errno code into an `io::Result<()>`. /// Translate a WASI errno code into an `io::Result<()>`.
@@ -6,89 +6,89 @@ use std::io;
/// TODO: Would it be better to have our own version of `io::Error` (and /// TODO: Would it be better to have our own version of `io::Error` (and
/// `io::Result`), rather than trying to shoehorn WASI errors into the /// `io::Result`), rather than trying to shoehorn WASI errors into the
/// libstd version? /// libstd version?
pub(crate) fn wasi_errno_to_io_error(errno: host::__wasi_errno_t) -> io::Result<()> { pub(crate) fn wasi_errno_to_io_error(errno: wasi::__wasi_errno_t) -> io::Result<()> {
#[cfg(unix)] #[cfg(unix)]
let raw_os_error = match errno { let raw_os_error = match errno {
host::__WASI_ESUCCESS => return Ok(()), wasi::__WASI_ESUCCESS => return Ok(()),
host::__WASI_EIO => libc::EIO, wasi::__WASI_EIO => libc::EIO,
host::__WASI_EPERM => libc::EPERM, wasi::__WASI_EPERM => libc::EPERM,
host::__WASI_EINVAL => libc::EINVAL, wasi::__WASI_EINVAL => libc::EINVAL,
host::__WASI_EPIPE => libc::EPIPE, wasi::__WASI_EPIPE => libc::EPIPE,
host::__WASI_ENOTCONN => libc::ENOTCONN, wasi::__WASI_ENOTCONN => libc::ENOTCONN,
host::__WASI_E2BIG => libc::E2BIG, wasi::__WASI_E2BIG => libc::E2BIG,
host::__WASI_EACCES => libc::EACCES, wasi::__WASI_EACCES => libc::EACCES,
host::__WASI_EADDRINUSE => libc::EADDRINUSE, wasi::__WASI_EADDRINUSE => libc::EADDRINUSE,
host::__WASI_EADDRNOTAVAIL => libc::EADDRNOTAVAIL, wasi::__WASI_EADDRNOTAVAIL => libc::EADDRNOTAVAIL,
host::__WASI_EAFNOSUPPORT => libc::EAFNOSUPPORT, wasi::__WASI_EAFNOSUPPORT => libc::EAFNOSUPPORT,
host::__WASI_EAGAIN => libc::EAGAIN, wasi::__WASI_EAGAIN => libc::EAGAIN,
host::__WASI_EALREADY => libc::EALREADY, wasi::__WASI_EALREADY => libc::EALREADY,
host::__WASI_EBADF => libc::EBADF, wasi::__WASI_EBADF => libc::EBADF,
host::__WASI_EBADMSG => libc::EBADMSG, wasi::__WASI_EBADMSG => libc::EBADMSG,
host::__WASI_EBUSY => libc::EBUSY, wasi::__WASI_EBUSY => libc::EBUSY,
host::__WASI_ECANCELED => libc::ECANCELED, wasi::__WASI_ECANCELED => libc::ECANCELED,
host::__WASI_ECHILD => libc::ECHILD, wasi::__WASI_ECHILD => libc::ECHILD,
host::__WASI_ECONNABORTED => libc::ECONNABORTED, wasi::__WASI_ECONNABORTED => libc::ECONNABORTED,
host::__WASI_ECONNREFUSED => libc::ECONNREFUSED, wasi::__WASI_ECONNREFUSED => libc::ECONNREFUSED,
host::__WASI_ECONNRESET => libc::ECONNRESET, wasi::__WASI_ECONNRESET => libc::ECONNRESET,
host::__WASI_EDEADLK => libc::EDEADLK, wasi::__WASI_EDEADLK => libc::EDEADLK,
host::__WASI_EDESTADDRREQ => libc::EDESTADDRREQ, wasi::__WASI_EDESTADDRREQ => libc::EDESTADDRREQ,
host::__WASI_EDOM => libc::EDOM, wasi::__WASI_EDOM => libc::EDOM,
host::__WASI_EDQUOT => libc::EDQUOT, wasi::__WASI_EDQUOT => libc::EDQUOT,
host::__WASI_EEXIST => libc::EEXIST, wasi::__WASI_EEXIST => libc::EEXIST,
host::__WASI_EFAULT => libc::EFAULT, wasi::__WASI_EFAULT => libc::EFAULT,
host::__WASI_EFBIG => libc::EFBIG, wasi::__WASI_EFBIG => libc::EFBIG,
host::__WASI_EHOSTUNREACH => libc::EHOSTUNREACH, wasi::__WASI_EHOSTUNREACH => libc::EHOSTUNREACH,
host::__WASI_EIDRM => libc::EIDRM, wasi::__WASI_EIDRM => libc::EIDRM,
host::__WASI_EILSEQ => libc::EILSEQ, wasi::__WASI_EILSEQ => libc::EILSEQ,
host::__WASI_EINPROGRESS => libc::EINPROGRESS, wasi::__WASI_EINPROGRESS => libc::EINPROGRESS,
host::__WASI_EINTR => libc::EINTR, wasi::__WASI_EINTR => libc::EINTR,
host::__WASI_EISCONN => libc::EISCONN, wasi::__WASI_EISCONN => libc::EISCONN,
host::__WASI_EISDIR => libc::EISDIR, wasi::__WASI_EISDIR => libc::EISDIR,
host::__WASI_ELOOP => libc::ELOOP, wasi::__WASI_ELOOP => libc::ELOOP,
host::__WASI_EMFILE => libc::EMFILE, wasi::__WASI_EMFILE => libc::EMFILE,
host::__WASI_EMLINK => libc::EMLINK, wasi::__WASI_EMLINK => libc::EMLINK,
host::__WASI_EMSGSIZE => libc::EMSGSIZE, wasi::__WASI_EMSGSIZE => libc::EMSGSIZE,
host::__WASI_EMULTIHOP => libc::EMULTIHOP, wasi::__WASI_EMULTIHOP => libc::EMULTIHOP,
host::__WASI_ENAMETOOLONG => libc::ENAMETOOLONG, wasi::__WASI_ENAMETOOLONG => libc::ENAMETOOLONG,
host::__WASI_ENETDOWN => libc::ENETDOWN, wasi::__WASI_ENETDOWN => libc::ENETDOWN,
host::__WASI_ENETRESET => libc::ENETRESET, wasi::__WASI_ENETRESET => libc::ENETRESET,
host::__WASI_ENETUNREACH => libc::ENETUNREACH, wasi::__WASI_ENETUNREACH => libc::ENETUNREACH,
host::__WASI_ENFILE => libc::ENFILE, wasi::__WASI_ENFILE => libc::ENFILE,
host::__WASI_ENOBUFS => libc::ENOBUFS, wasi::__WASI_ENOBUFS => libc::ENOBUFS,
host::__WASI_ENODEV => libc::ENODEV, wasi::__WASI_ENODEV => libc::ENODEV,
host::__WASI_ENOENT => libc::ENOENT, wasi::__WASI_ENOENT => libc::ENOENT,
host::__WASI_ENOEXEC => libc::ENOEXEC, wasi::__WASI_ENOEXEC => libc::ENOEXEC,
host::__WASI_ENOLCK => libc::ENOLCK, wasi::__WASI_ENOLCK => libc::ENOLCK,
host::__WASI_ENOLINK => libc::ENOLINK, wasi::__WASI_ENOLINK => libc::ENOLINK,
host::__WASI_ENOMEM => libc::ENOMEM, wasi::__WASI_ENOMEM => libc::ENOMEM,
host::__WASI_ENOMSG => libc::ENOMSG, wasi::__WASI_ENOMSG => libc::ENOMSG,
host::__WASI_ENOPROTOOPT => libc::ENOPROTOOPT, wasi::__WASI_ENOPROTOOPT => libc::ENOPROTOOPT,
host::__WASI_ENOSPC => libc::ENOSPC, wasi::__WASI_ENOSPC => libc::ENOSPC,
host::__WASI_ENOSYS => libc::ENOSYS, wasi::__WASI_ENOSYS => libc::ENOSYS,
host::__WASI_ENOTDIR => libc::ENOTDIR, wasi::__WASI_ENOTDIR => libc::ENOTDIR,
host::__WASI_ENOTEMPTY => libc::ENOTEMPTY, wasi::__WASI_ENOTEMPTY => libc::ENOTEMPTY,
host::__WASI_ENOTRECOVERABLE => libc::ENOTRECOVERABLE, wasi::__WASI_ENOTRECOVERABLE => libc::ENOTRECOVERABLE,
host::__WASI_ENOTSOCK => libc::ENOTSOCK, wasi::__WASI_ENOTSOCK => libc::ENOTSOCK,
host::__WASI_ENOTSUP => libc::ENOTSUP, wasi::__WASI_ENOTSUP => libc::ENOTSUP,
host::__WASI_ENOTTY => libc::ENOTTY, wasi::__WASI_ENOTTY => libc::ENOTTY,
host::__WASI_ENXIO => libc::ENXIO, wasi::__WASI_ENXIO => libc::ENXIO,
host::__WASI_EOVERFLOW => libc::EOVERFLOW, wasi::__WASI_EOVERFLOW => libc::EOVERFLOW,
host::__WASI_EOWNERDEAD => libc::EOWNERDEAD, wasi::__WASI_EOWNERDEAD => libc::EOWNERDEAD,
host::__WASI_EPROTO => libc::EPROTO, wasi::__WASI_EPROTO => libc::EPROTO,
host::__WASI_EPROTONOSUPPORT => libc::EPROTONOSUPPORT, wasi::__WASI_EPROTONOSUPPORT => libc::EPROTONOSUPPORT,
host::__WASI_EPROTOTYPE => libc::EPROTOTYPE, wasi::__WASI_EPROTOTYPE => libc::EPROTOTYPE,
host::__WASI_ERANGE => libc::ERANGE, wasi::__WASI_ERANGE => libc::ERANGE,
host::__WASI_EROFS => libc::EROFS, wasi::__WASI_EROFS => libc::EROFS,
host::__WASI_ESPIPE => libc::ESPIPE, wasi::__WASI_ESPIPE => libc::ESPIPE,
host::__WASI_ESRCH => libc::ESRCH, wasi::__WASI_ESRCH => libc::ESRCH,
host::__WASI_ESTALE => libc::ESTALE, wasi::__WASI_ESTALE => libc::ESTALE,
host::__WASI_ETIMEDOUT => libc::ETIMEDOUT, wasi::__WASI_ETIMEDOUT => libc::ETIMEDOUT,
host::__WASI_ETXTBSY => libc::ETXTBSY, wasi::__WASI_ETXTBSY => libc::ETXTBSY,
host::__WASI_EXDEV => libc::EXDEV, wasi::__WASI_EXDEV => libc::EXDEV,
#[cfg(target_os = "wasi")] #[cfg(target_os = "wasi")]
host::__WASI_ENOTCAPABLE => libc::ENOTCAPABLE, wasi::__WASI_ENOTCAPABLE => libc::ENOTCAPABLE,
#[cfg(not(target_os = "wasi"))] #[cfg(not(target_os = "wasi"))]
host::__WASI_ENOTCAPABLE => libc::EIO, wasi::__WASI_ENOTCAPABLE => libc::EIO,
_ => panic!("unexpected wasi errno value"), _ => panic!("unexpected wasi errno value"),
}; };
@@ -97,82 +97,82 @@ pub(crate) fn wasi_errno_to_io_error(errno: host::__wasi_errno_t) -> io::Result<
#[cfg(windows)] #[cfg(windows)]
let raw_os_error = match errno { let raw_os_error = match errno {
host::__WASI_ESUCCESS => return Ok(()), wasi::__WASI_ESUCCESS => return Ok(()),
host::__WASI_EINVAL => WSAEINVAL, wasi::__WASI_EINVAL => WSAEINVAL,
host::__WASI_EPIPE => ERROR_BROKEN_PIPE, wasi::__WASI_EPIPE => ERROR_BROKEN_PIPE,
host::__WASI_ENOTCONN => WSAENOTCONN, wasi::__WASI_ENOTCONN => WSAENOTCONN,
host::__WASI_EPERM | host::__WASI_EACCES => ERROR_ACCESS_DENIED, wasi::__WASI_EPERM | wasi::__WASI_EACCES => ERROR_ACCESS_DENIED,
host::__WASI_EADDRINUSE => WSAEADDRINUSE, wasi::__WASI_EADDRINUSE => WSAEADDRINUSE,
host::__WASI_EADDRNOTAVAIL => WSAEADDRNOTAVAIL, wasi::__WASI_EADDRNOTAVAIL => WSAEADDRNOTAVAIL,
host::__WASI_EAGAIN => WSAEWOULDBLOCK, wasi::__WASI_EAGAIN => WSAEWOULDBLOCK,
host::__WASI_ECONNABORTED => WSAECONNABORTED, wasi::__WASI_ECONNABORTED => WSAECONNABORTED,
host::__WASI_ECONNREFUSED => WSAECONNREFUSED, wasi::__WASI_ECONNREFUSED => WSAECONNREFUSED,
host::__WASI_ECONNRESET => WSAECONNRESET, wasi::__WASI_ECONNRESET => WSAECONNRESET,
host::__WASI_EEXIST => ERROR_ALREADY_EXISTS, wasi::__WASI_EEXIST => ERROR_ALREADY_EXISTS,
host::__WASI_ENOENT => ERROR_FILE_NOT_FOUND, wasi::__WASI_ENOENT => ERROR_FILE_NOT_FOUND,
host::__WASI_ETIMEDOUT => WSAETIMEDOUT, wasi::__WASI_ETIMEDOUT => WSAETIMEDOUT,
host::__WASI_EAFNOSUPPORT => WSAEAFNOSUPPORT, wasi::__WASI_EAFNOSUPPORT => WSAEAFNOSUPPORT,
host::__WASI_EALREADY => WSAEALREADY, wasi::__WASI_EALREADY => WSAEALREADY,
host::__WASI_EBADF => WSAEBADF, wasi::__WASI_EBADF => WSAEBADF,
host::__WASI_EDESTADDRREQ => WSAEDESTADDRREQ, wasi::__WASI_EDESTADDRREQ => WSAEDESTADDRREQ,
host::__WASI_EDQUOT => WSAEDQUOT, wasi::__WASI_EDQUOT => WSAEDQUOT,
host::__WASI_EFAULT => WSAEFAULT, wasi::__WASI_EFAULT => WSAEFAULT,
host::__WASI_EHOSTUNREACH => WSAEHOSTUNREACH, wasi::__WASI_EHOSTUNREACH => WSAEHOSTUNREACH,
host::__WASI_EINPROGRESS => WSAEINPROGRESS, wasi::__WASI_EINPROGRESS => WSAEINPROGRESS,
host::__WASI_EINTR => WSAEINTR, wasi::__WASI_EINTR => WSAEINTR,
host::__WASI_EISCONN => WSAEISCONN, wasi::__WASI_EISCONN => WSAEISCONN,
host::__WASI_ELOOP => WSAELOOP, wasi::__WASI_ELOOP => WSAELOOP,
host::__WASI_EMFILE => WSAEMFILE, wasi::__WASI_EMFILE => WSAEMFILE,
host::__WASI_EMSGSIZE => WSAEMSGSIZE, wasi::__WASI_EMSGSIZE => WSAEMSGSIZE,
host::__WASI_ENAMETOOLONG => WSAENAMETOOLONG, wasi::__WASI_ENAMETOOLONG => WSAENAMETOOLONG,
host::__WASI_ENETDOWN => WSAENETDOWN, wasi::__WASI_ENETDOWN => WSAENETDOWN,
host::__WASI_ENETRESET => WSAENETRESET, wasi::__WASI_ENETRESET => WSAENETRESET,
host::__WASI_ENETUNREACH => WSAENETUNREACH, wasi::__WASI_ENETUNREACH => WSAENETUNREACH,
host::__WASI_ENOBUFS => WSAENOBUFS, wasi::__WASI_ENOBUFS => WSAENOBUFS,
host::__WASI_ENOPROTOOPT => WSAENOPROTOOPT, wasi::__WASI_ENOPROTOOPT => WSAENOPROTOOPT,
host::__WASI_ENOTEMPTY => WSAENOTEMPTY, wasi::__WASI_ENOTEMPTY => WSAENOTEMPTY,
host::__WASI_ENOTSOCK => WSAENOTSOCK, wasi::__WASI_ENOTSOCK => WSAENOTSOCK,
host::__WASI_EPROTONOSUPPORT => WSAEPROTONOSUPPORT, wasi::__WASI_EPROTONOSUPPORT => WSAEPROTONOSUPPORT,
host::__WASI_EPROTOTYPE => WSAEPROTOTYPE, wasi::__WASI_EPROTOTYPE => WSAEPROTOTYPE,
host::__WASI_ESTALE => WSAESTALE, wasi::__WASI_ESTALE => WSAESTALE,
host::__WASI_EIO wasi::__WASI_EIO
| host::__WASI_EISDIR | wasi::__WASI_EISDIR
| host::__WASI_E2BIG | wasi::__WASI_E2BIG
| host::__WASI_EBADMSG | wasi::__WASI_EBADMSG
| host::__WASI_EBUSY | wasi::__WASI_EBUSY
| host::__WASI_ECANCELED | wasi::__WASI_ECANCELED
| host::__WASI_ECHILD | wasi::__WASI_ECHILD
| host::__WASI_EDEADLK | wasi::__WASI_EDEADLK
| host::__WASI_EDOM | wasi::__WASI_EDOM
| host::__WASI_EFBIG | wasi::__WASI_EFBIG
| host::__WASI_EIDRM | wasi::__WASI_EIDRM
| host::__WASI_EILSEQ | wasi::__WASI_EILSEQ
| host::__WASI_EMLINK | wasi::__WASI_EMLINK
| host::__WASI_EMULTIHOP | wasi::__WASI_EMULTIHOP
| host::__WASI_ENFILE | wasi::__WASI_ENFILE
| host::__WASI_ENODEV | wasi::__WASI_ENODEV
| host::__WASI_ENOEXEC | wasi::__WASI_ENOEXEC
| host::__WASI_ENOLCK | wasi::__WASI_ENOLCK
| host::__WASI_ENOLINK | wasi::__WASI_ENOLINK
| host::__WASI_ENOMEM | wasi::__WASI_ENOMEM
| host::__WASI_ENOMSG | wasi::__WASI_ENOMSG
| host::__WASI_ENOSPC | wasi::__WASI_ENOSPC
| host::__WASI_ENOSYS | wasi::__WASI_ENOSYS
| host::__WASI_ENOTDIR | wasi::__WASI_ENOTDIR
| host::__WASI_ENOTRECOVERABLE | wasi::__WASI_ENOTRECOVERABLE
| host::__WASI_ENOTSUP | wasi::__WASI_ENOTSUP
| host::__WASI_ENOTTY | wasi::__WASI_ENOTTY
| host::__WASI_ENXIO | wasi::__WASI_ENXIO
| host::__WASI_EOVERFLOW | wasi::__WASI_EOVERFLOW
| host::__WASI_EOWNERDEAD | wasi::__WASI_EOWNERDEAD
| host::__WASI_EPROTO | wasi::__WASI_EPROTO
| host::__WASI_ERANGE | wasi::__WASI_ERANGE
| host::__WASI_EROFS | wasi::__WASI_EROFS
| host::__WASI_ESPIPE | wasi::__WASI_ESPIPE
| host::__WASI_ESRCH | wasi::__WASI_ESRCH
| host::__WASI_ETXTBSY | wasi::__WASI_ETXTBSY
| host::__WASI_EXDEV | wasi::__WASI_EXDEV
| host::__WASI_ENOTCAPABLE => { | wasi::__WASI_ENOTCAPABLE => {
return Err(io::Error::new(io::ErrorKind::Other, error_str(errno))) return Err(io::Error::new(io::ErrorKind::Other, error_str(errno)))
} }
_ => panic!("unrecognized WASI errno value"), _ => panic!("unrecognized WASI errno value"),
@@ -182,84 +182,84 @@ pub(crate) fn wasi_errno_to_io_error(errno: host::__wasi_errno_t) -> io::Result<
} }
#[cfg(windows)] #[cfg(windows)]
fn error_str(errno: host::__wasi_errno_t) -> &'static str { fn error_str(errno: wasi::__wasi_errno_t) -> &'static str {
match errno { match errno {
host::__WASI_E2BIG => "Argument list too long", wasi::__WASI_E2BIG => "Argument list too long",
host::__WASI_EACCES => "Permission denied", wasi::__WASI_EACCES => "Permission denied",
host::__WASI_EADDRINUSE => "Address in use", wasi::__WASI_EADDRINUSE => "Address in use",
host::__WASI_EADDRNOTAVAIL => "Address not available", wasi::__WASI_EADDRNOTAVAIL => "Address not available",
host::__WASI_EAFNOSUPPORT => "Address family not supported by protocol", wasi::__WASI_EAFNOSUPPORT => "Address family not supported by protocol",
host::__WASI_EAGAIN => "Resource temporarily unavailable", wasi::__WASI_EAGAIN => "Resource temporarily unavailable",
host::__WASI_EALREADY => "Operation already in progress", wasi::__WASI_EALREADY => "Operation already in progress",
host::__WASI_EBADF => "Bad file descriptor", wasi::__WASI_EBADF => "Bad file descriptor",
host::__WASI_EBADMSG => "Bad message", wasi::__WASI_EBADMSG => "Bad message",
host::__WASI_EBUSY => "Resource busy", wasi::__WASI_EBUSY => "Resource busy",
host::__WASI_ECANCELED => "Operation canceled", wasi::__WASI_ECANCELED => "Operation canceled",
host::__WASI_ECHILD => "No child process", wasi::__WASI_ECHILD => "No child process",
host::__WASI_ECONNABORTED => "Connection aborted", wasi::__WASI_ECONNABORTED => "Connection aborted",
host::__WASI_ECONNREFUSED => "Connection refused", wasi::__WASI_ECONNREFUSED => "Connection refused",
host::__WASI_ECONNRESET => "Connection reset by peer", wasi::__WASI_ECONNRESET => "Connection reset by peer",
host::__WASI_EDEADLK => "Resource deadlock would occur", wasi::__WASI_EDEADLK => "Resource deadlock would occur",
host::__WASI_EDESTADDRREQ => "Destination address required", wasi::__WASI_EDESTADDRREQ => "Destination address required",
host::__WASI_EDOM => "Domain error", wasi::__WASI_EDOM => "Domain error",
host::__WASI_EDQUOT => "Quota exceeded", wasi::__WASI_EDQUOT => "Quota exceeded",
host::__WASI_EEXIST => "File exists", wasi::__WASI_EEXIST => "File exists",
host::__WASI_EFAULT => "Bad address", wasi::__WASI_EFAULT => "Bad address",
host::__WASI_EFBIG => "File too large", wasi::__WASI_EFBIG => "File too large",
host::__WASI_EHOSTUNREACH => "Host is unreachable", wasi::__WASI_EHOSTUNREACH => "Host is unreachable",
host::__WASI_EIDRM => "Identifier removed", wasi::__WASI_EIDRM => "Identifier removed",
host::__WASI_EILSEQ => "Illegal byte sequence", wasi::__WASI_EILSEQ => "Illegal byte sequence",
host::__WASI_EINPROGRESS => "Operation in progress", wasi::__WASI_EINPROGRESS => "Operation in progress",
host::__WASI_EINTR => "Interrupted system call", wasi::__WASI_EINTR => "Interrupted system call",
host::__WASI_EINVAL => "Invalid argument", wasi::__WASI_EINVAL => "Invalid argument",
host::__WASI_EIO => "Remote I/O error", wasi::__WASI_EIO => "Remote I/O error",
host::__WASI_EISCONN => "Socket is connected", wasi::__WASI_EISCONN => "Socket is connected",
host::__WASI_EISDIR => "Is a directory", wasi::__WASI_EISDIR => "Is a directory",
host::__WASI_ELOOP => "Symbolic link loop", wasi::__WASI_ELOOP => "Symbolic link loop",
host::__WASI_EMFILE => "No file descriptors available", wasi::__WASI_EMFILE => "No file descriptors available",
host::__WASI_EMLINK => "Too many links", wasi::__WASI_EMLINK => "Too many links",
host::__WASI_EMSGSIZE => "Message too large", wasi::__WASI_EMSGSIZE => "Message too large",
host::__WASI_EMULTIHOP => "Multihop attempted", wasi::__WASI_EMULTIHOP => "Multihop attempted",
host::__WASI_ENAMETOOLONG => "Filename too long", wasi::__WASI_ENAMETOOLONG => "Filename too long",
host::__WASI_ENETDOWN => "Network is down", wasi::__WASI_ENETDOWN => "Network is down",
host::__WASI_ENETRESET => "Connection reset by network", wasi::__WASI_ENETRESET => "Connection reset by network",
host::__WASI_ENETUNREACH => "Network unreachable", wasi::__WASI_ENETUNREACH => "Network unreachable",
host::__WASI_ENFILE => "Too many open files in system", wasi::__WASI_ENFILE => "Too many open files in system",
host::__WASI_ENOBUFS => "No buffer space available", wasi::__WASI_ENOBUFS => "No buffer space available",
host::__WASI_ENODEV => "No such device", wasi::__WASI_ENODEV => "No such device",
host::__WASI_ENOENT => "No such file or directory", wasi::__WASI_ENOENT => "No such file or directory",
host::__WASI_ENOEXEC => "Exec format error", wasi::__WASI_ENOEXEC => "Exec format error",
host::__WASI_ENOLCK => "No locks available", wasi::__WASI_ENOLCK => "No locks available",
host::__WASI_ENOLINK => "Link has been severed", wasi::__WASI_ENOLINK => "Link has been severed",
host::__WASI_ENOMEM => "Out of memory", wasi::__WASI_ENOMEM => "Out of memory",
host::__WASI_ENOMSG => "No message of desired type", wasi::__WASI_ENOMSG => "No message of desired type",
host::__WASI_ENOPROTOOPT => "Protocol not available", wasi::__WASI_ENOPROTOOPT => "Protocol not available",
host::__WASI_ENOSPC => "No space left on device", wasi::__WASI_ENOSPC => "No space left on device",
host::__WASI_ENOSYS => "Function not implemented", wasi::__WASI_ENOSYS => "Function not implemented",
host::__WASI_ENOTCONN => "Socket not connected", wasi::__WASI_ENOTCONN => "Socket not connected",
host::__WASI_ENOTDIR => "Not a directory", wasi::__WASI_ENOTDIR => "Not a directory",
host::__WASI_ENOTEMPTY => "Directory not empty", wasi::__WASI_ENOTEMPTY => "Directory not empty",
host::__WASI_ENOTRECOVERABLE => "State not recoverable", wasi::__WASI_ENOTRECOVERABLE => "State not recoverable",
host::__WASI_ENOTSOCK => "Not a socket", wasi::__WASI_ENOTSOCK => "Not a socket",
host::__WASI_ENOTSUP => "Not supported", wasi::__WASI_ENOTSUP => "Not supported",
host::__WASI_ENOTTY => "Not a tty", wasi::__WASI_ENOTTY => "Not a tty",
host::__WASI_ENXIO => "No such device or address", wasi::__WASI_ENXIO => "No such device or address",
host::__WASI_EOVERFLOW => "Value too large for data type", wasi::__WASI_EOVERFLOW => "Value too large for data type",
host::__WASI_EOWNERDEAD => "Previous owner died", wasi::__WASI_EOWNERDEAD => "Previous owner died",
host::__WASI_EPERM => "Operation not permitted", wasi::__WASI_EPERM => "Operation not permitted",
host::__WASI_EPIPE => "Broken pipe", wasi::__WASI_EPIPE => "Broken pipe",
host::__WASI_EPROTO => "Protocol error", wasi::__WASI_EPROTO => "Protocol error",
host::__WASI_EPROTONOSUPPORT => "Protocol not supported", wasi::__WASI_EPROTONOSUPPORT => "Protocol not supported",
host::__WASI_EPROTOTYPE => "Protocol wrong type for socket", wasi::__WASI_EPROTOTYPE => "Protocol wrong type for socket",
host::__WASI_ERANGE => "Result not representable", wasi::__WASI_ERANGE => "Result not representable",
host::__WASI_EROFS => "Read-only file system", wasi::__WASI_EROFS => "Read-only file system",
host::__WASI_ESPIPE => "Invalid seek", wasi::__WASI_ESPIPE => "Invalid seek",
host::__WASI_ESRCH => "No such process", wasi::__WASI_ESRCH => "No such process",
host::__WASI_ESTALE => "Stale file handle", wasi::__WASI_ESTALE => "Stale file handle",
host::__WASI_ETIMEDOUT => "Operation timed out", wasi::__WASI_ETIMEDOUT => "Operation timed out",
host::__WASI_ETXTBSY => "Text file busy", wasi::__WASI_ETXTBSY => "Text file busy",
host::__WASI_EXDEV => "Cross-device link", wasi::__WASI_EXDEV => "Cross-device link",
host::__WASI_ENOTCAPABLE => "Capabilities insufficient", wasi::__WASI_ENOTCAPABLE => "Capabilities insufficient",
_ => panic!("unrecognized WASI errno value"), _ => panic!("unrecognized WASI errno value"),
} }
} }

View File

@@ -1,5 +1,5 @@
use crate::fs::{error::wasi_errno_to_io_error, Metadata}; use crate::fs::{error::wasi_errno_to_io_error, Metadata};
use crate::{host, hostcalls, WasiCtx}; use crate::{host, hostcalls, wasi, WasiCtx};
use std::io; use std::io;
/// A reference to an open file on the filesystem. /// A reference to an open file on the filesystem.
@@ -16,7 +16,7 @@ use std::io;
/// [`Dir::create_file`]: struct.Dir.html#method.create_file /// [`Dir::create_file`]: struct.Dir.html#method.create_file
pub struct File<'ctx> { pub struct File<'ctx> {
ctx: &'ctx mut WasiCtx, ctx: &'ctx mut WasiCtx,
fd: host::__wasi_fd_t, fd: wasi::__wasi_fd_t,
} }
impl<'ctx> File<'ctx> { impl<'ctx> File<'ctx> {
@@ -25,7 +25,7 @@ impl<'ctx> File<'ctx> {
/// This corresponds to [`std::fs::File::from_raw_fd`]. /// This corresponds to [`std::fs::File::from_raw_fd`].
/// ///
/// [`std::fs::File::from_raw_fd`]: https://doc.rust-lang.org/std/fs/struct.File.html#method.from_raw_fd /// [`std::fs::File::from_raw_fd`]: https://doc.rust-lang.org/std/fs/struct.File.html#method.from_raw_fd
pub unsafe fn from_raw_wasi_fd(ctx: &'ctx mut WasiCtx, fd: host::__wasi_fd_t) -> Self { pub unsafe fn from_raw_wasi_fd(ctx: &'ctx mut WasiCtx, fd: wasi::__wasi_fd_t) -> Self {
Self { ctx, fd } Self { ctx, fd }
} }

View File

@@ -1,5 +1,5 @@
use crate::fs::DirEntry; use crate::fs::DirEntry;
use crate::{host, hostcalls}; use crate::{hostcalls, wasi};
/// Iterator over the entries in a directory. /// Iterator over the entries in a directory.
/// ///
@@ -9,12 +9,12 @@ use crate::{host, hostcalls};
/// ///
/// [`std::fs::ReadDir`]: https://doc.rust-lang.org/std/fs/struct.ReadDir.html /// [`std::fs::ReadDir`]: https://doc.rust-lang.org/std/fs/struct.ReadDir.html
pub struct ReadDir { pub struct ReadDir {
fd: host::__wasi_fd_t, fd: wasi::__wasi_fd_t,
} }
impl ReadDir { impl ReadDir {
/// Constructs a new instance of `Self` from the given raw WASI file descriptor. /// Constructs a new instance of `Self` from the given raw WASI file descriptor.
pub unsafe fn from_raw_wasi_fd(fd: host::__wasi_fd_t) -> Self { pub unsafe fn from_raw_wasi_fd(fd: wasi::__wasi_fd_t) -> Self {
Self { fd } Self { fd }
} }
} }

View File

@@ -1,5 +1,6 @@
use crate::{Error, Result}; use crate::{Error, Result};
use std::convert::TryInto; use std::convert::TryInto;
use std::str;
use std::time::{SystemTime, UNIX_EPOCH}; use std::time::{SystemTime, UNIX_EPOCH};
pub(crate) fn systemtime_to_timestamp(st: SystemTime) -> Result<u64> { pub(crate) fn systemtime_to_timestamp(st: SystemTime) -> Result<u64> {
@@ -9,3 +10,11 @@ pub(crate) fn systemtime_to_timestamp(st: SystemTime) -> Result<u64> {
.try_into() .try_into()
.map_err(Into::into) // u128 doesn't fit into u64 .map_err(Into::into) // u128 doesn't fit into u64
} }
/// Creates not-owned WASI path from byte slice.
///
/// NB WASI spec requires bytes to be valid UTF-8. Otherwise,
/// `__WASI_EILSEQ` error is returned.
pub(crate) fn path_from_slice<'a>(s: &'a [u8]) -> Result<&'a str> {
str::from_utf8(s).map_err(|_| Error::EILSEQ)
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,256 +1,256 @@
#![allow(non_camel_case_types)] #![allow(non_camel_case_types)]
use crate::ctx::WasiCtx; use crate::ctx::WasiCtx;
use crate::wasm32; use crate::{wasi, wasi32};
hostcalls! { hostcalls! {
pub unsafe fn fd_close(wasi_ctx: &mut WasiCtx, fd: wasm32::__wasi_fd_t,) -> wasm32::__wasi_errno_t; pub unsafe fn fd_close(wasi_ctx: &mut WasiCtx, fd: wasi::__wasi_fd_t,) -> wasi::__wasi_errno_t;
pub unsafe fn fd_datasync(wasi_ctx: &WasiCtx, fd: wasm32::__wasi_fd_t,) -> wasm32::__wasi_errno_t; pub unsafe fn fd_datasync(wasi_ctx: &WasiCtx, fd: wasi::__wasi_fd_t,) -> wasi::__wasi_errno_t;
pub unsafe fn fd_pread( pub unsafe fn fd_pread(
wasi_ctx: &WasiCtx, wasi_ctx: &WasiCtx,
memory: &mut [u8], memory: &mut [u8],
fd: wasm32::__wasi_fd_t, fd: wasi::__wasi_fd_t,
iovs_ptr: wasm32::uintptr_t, iovs_ptr: wasi32::uintptr_t,
iovs_len: wasm32::size_t, iovs_len: wasi32::size_t,
offset: wasm32::__wasi_filesize_t, offset: wasi::__wasi_filesize_t,
nread: wasm32::uintptr_t, nread: wasi32::uintptr_t,
) -> wasm32::__wasi_errno_t; ) -> wasi::__wasi_errno_t;
pub unsafe fn fd_pwrite( pub unsafe fn fd_pwrite(
wasi_ctx: &WasiCtx, wasi_ctx: &WasiCtx,
memory: &mut [u8], memory: &mut [u8],
fd: wasm32::__wasi_fd_t, fd: wasi::__wasi_fd_t,
iovs_ptr: wasm32::uintptr_t, iovs_ptr: wasi32::uintptr_t,
iovs_len: wasm32::size_t, iovs_len: wasi32::size_t,
offset: wasm32::__wasi_filesize_t, offset: wasi::__wasi_filesize_t,
nwritten: wasm32::uintptr_t, nwritten: wasi32::uintptr_t,
) -> wasm32::__wasi_errno_t; ) -> wasi::__wasi_errno_t;
pub unsafe fn fd_read( pub unsafe fn fd_read(
wasi_ctx: &mut WasiCtx, wasi_ctx: &mut WasiCtx,
memory: &mut [u8], memory: &mut [u8],
fd: wasm32::__wasi_fd_t, fd: wasi::__wasi_fd_t,
iovs_ptr: wasm32::uintptr_t, iovs_ptr: wasi32::uintptr_t,
iovs_len: wasm32::size_t, iovs_len: wasi32::size_t,
nread: wasm32::uintptr_t, nread: wasi32::uintptr_t,
) -> wasm32::__wasi_errno_t; ) -> wasi::__wasi_errno_t;
pub unsafe fn fd_renumber( pub unsafe fn fd_renumber(
wasi_ctx: &mut WasiCtx, wasi_ctx: &mut WasiCtx,
from: wasm32::__wasi_fd_t, from: wasi::__wasi_fd_t,
to: wasm32::__wasi_fd_t, to: wasi::__wasi_fd_t,
) -> wasm32::__wasi_errno_t; ) -> wasi::__wasi_errno_t;
pub unsafe fn fd_seek( pub unsafe fn fd_seek(
wasi_ctx: &mut WasiCtx, wasi_ctx: &mut WasiCtx,
memory: &mut [u8], memory: &mut [u8],
fd: wasm32::__wasi_fd_t, fd: wasi::__wasi_fd_t,
offset: wasm32::__wasi_filedelta_t, offset: wasi::__wasi_filedelta_t,
whence: wasm32::__wasi_whence_t, whence: wasi::__wasi_whence_t,
newoffset: wasm32::uintptr_t, newoffset: wasi32::uintptr_t,
) -> wasm32::__wasi_errno_t; ) -> wasi::__wasi_errno_t;
pub unsafe fn fd_tell( pub unsafe fn fd_tell(
wasi_ctx: &mut WasiCtx, wasi_ctx: &mut WasiCtx,
memory: &mut [u8], memory: &mut [u8],
fd: wasm32::__wasi_fd_t, fd: wasi::__wasi_fd_t,
newoffset: wasm32::uintptr_t, newoffset: wasi32::uintptr_t,
) -> wasm32::__wasi_errno_t; ) -> wasi::__wasi_errno_t;
pub unsafe fn fd_fdstat_get( pub unsafe fn fd_fdstat_get(
wasi_ctx: &WasiCtx, wasi_ctx: &WasiCtx,
memory: &mut [u8], memory: &mut [u8],
fd: wasm32::__wasi_fd_t, fd: wasi::__wasi_fd_t,
fdstat_ptr: wasm32::uintptr_t, fdstat_ptr: wasi32::uintptr_t,
) -> wasm32::__wasi_errno_t; ) -> wasi::__wasi_errno_t;
pub unsafe fn fd_fdstat_set_flags( pub unsafe fn fd_fdstat_set_flags(
wasi_ctx: &WasiCtx, wasi_ctx: &WasiCtx,
fd: wasm32::__wasi_fd_t, fd: wasi::__wasi_fd_t,
fdflags: wasm32::__wasi_fdflags_t, fdflags: wasi::__wasi_fdflags_t,
) -> wasm32::__wasi_errno_t; ) -> wasi::__wasi_errno_t;
pub unsafe fn fd_fdstat_set_rights( pub unsafe fn fd_fdstat_set_rights(
wasi_ctx: &mut WasiCtx, wasi_ctx: &mut WasiCtx,
fd: wasm32::__wasi_fd_t, fd: wasi::__wasi_fd_t,
fs_rights_base: wasm32::__wasi_rights_t, fs_rights_base: wasi::__wasi_rights_t,
fs_rights_inheriting: wasm32::__wasi_rights_t, fs_rights_inheriting: wasi::__wasi_rights_t,
) -> wasm32::__wasi_errno_t; ) -> wasi::__wasi_errno_t;
pub unsafe fn fd_sync(wasi_ctx: &WasiCtx, fd: wasm32::__wasi_fd_t,) -> wasm32::__wasi_errno_t; pub unsafe fn fd_sync(wasi_ctx: &WasiCtx, fd: wasi::__wasi_fd_t,) -> wasi::__wasi_errno_t;
pub unsafe fn fd_write( pub unsafe fn fd_write(
wasi_ctx: &mut WasiCtx, wasi_ctx: &mut WasiCtx,
memory: &mut [u8], memory: &mut [u8],
fd: wasm32::__wasi_fd_t, fd: wasi::__wasi_fd_t,
iovs_ptr: wasm32::uintptr_t, iovs_ptr: wasi32::uintptr_t,
iovs_len: wasm32::size_t, iovs_len: wasi32::size_t,
nwritten: wasm32::uintptr_t, nwritten: wasi32::uintptr_t,
) -> wasm32::__wasi_errno_t; ) -> wasi::__wasi_errno_t;
pub unsafe fn fd_advise( pub unsafe fn fd_advise(
wasi_ctx: &WasiCtx, wasi_ctx: &WasiCtx,
fd: wasm32::__wasi_fd_t, fd: wasi::__wasi_fd_t,
offset: wasm32::__wasi_filesize_t, offset: wasi::__wasi_filesize_t,
len: wasm32::__wasi_filesize_t, len: wasi::__wasi_filesize_t,
advice: wasm32::__wasi_advice_t, advice: wasi::__wasi_advice_t,
) -> wasm32::__wasi_errno_t; ) -> wasi::__wasi_errno_t;
pub unsafe fn fd_allocate( pub unsafe fn fd_allocate(
wasi_ctx: &WasiCtx, wasi_ctx: &WasiCtx,
fd: wasm32::__wasi_fd_t, fd: wasi::__wasi_fd_t,
offset: wasm32::__wasi_filesize_t, offset: wasi::__wasi_filesize_t,
len: wasm32::__wasi_filesize_t, len: wasi::__wasi_filesize_t,
) -> wasm32::__wasi_errno_t; ) -> wasi::__wasi_errno_t;
pub unsafe fn path_create_directory( pub unsafe fn path_create_directory(
wasi_ctx: &WasiCtx, wasi_ctx: &WasiCtx,
memory: &mut [u8], memory: &mut [u8],
dirfd: wasm32::__wasi_fd_t, dirfd: wasi::__wasi_fd_t,
path_ptr: wasm32::uintptr_t, path_ptr: wasi32::uintptr_t,
path_len: wasm32::size_t, path_len: wasi32::size_t,
) -> wasm32::__wasi_errno_t; ) -> wasi::__wasi_errno_t;
pub unsafe fn path_link( pub unsafe fn path_link(
wasi_ctx: &WasiCtx, wasi_ctx: &WasiCtx,
memory: &mut [u8], memory: &mut [u8],
old_dirfd: wasm32::__wasi_fd_t, old_dirfd: wasi::__wasi_fd_t,
old_flags: wasm32::__wasi_lookupflags_t, old_flags: wasi::__wasi_lookupflags_t,
old_path_ptr: wasm32::uintptr_t, old_path_ptr: wasi32::uintptr_t,
old_path_len: wasm32::size_t, old_path_len: wasi32::size_t,
new_dirfd: wasm32::__wasi_fd_t, new_dirfd: wasi::__wasi_fd_t,
new_path_ptr: wasm32::uintptr_t, new_path_ptr: wasi32::uintptr_t,
new_path_len: wasm32::size_t, new_path_len: wasi32::size_t,
) -> wasm32::__wasi_errno_t; ) -> wasi::__wasi_errno_t;
pub unsafe fn path_open( pub unsafe fn path_open(
wasi_ctx: &mut WasiCtx, wasi_ctx: &mut WasiCtx,
memory: &mut [u8], memory: &mut [u8],
dirfd: wasm32::__wasi_fd_t, dirfd: wasi::__wasi_fd_t,
dirflags: wasm32::__wasi_lookupflags_t, dirflags: wasi::__wasi_lookupflags_t,
path_ptr: wasm32::uintptr_t, path_ptr: wasi32::uintptr_t,
path_len: wasm32::size_t, path_len: wasi32::size_t,
oflags: wasm32::__wasi_oflags_t, oflags: wasi::__wasi_oflags_t,
fs_rights_base: wasm32::__wasi_rights_t, fs_rights_base: wasi::__wasi_rights_t,
fs_rights_inheriting: wasm32::__wasi_rights_t, fs_rights_inheriting: wasi::__wasi_rights_t,
fs_flags: wasm32::__wasi_fdflags_t, fs_flags: wasi::__wasi_fdflags_t,
fd_out_ptr: wasm32::uintptr_t, fd_out_ptr: wasi32::uintptr_t,
) -> wasm32::__wasi_errno_t; ) -> wasi::__wasi_errno_t;
pub unsafe fn fd_readdir( pub unsafe fn fd_readdir(
wasi_ctx: &mut WasiCtx, wasi_ctx: &mut WasiCtx,
memory: &mut [u8], memory: &mut [u8],
fd: wasm32::__wasi_fd_t, fd: wasi::__wasi_fd_t,
buf: wasm32::uintptr_t, buf: wasi32::uintptr_t,
buf_len: wasm32::size_t, buf_len: wasi32::size_t,
cookie: wasm32::__wasi_dircookie_t, cookie: wasi::__wasi_dircookie_t,
buf_used: wasm32::uintptr_t, buf_used: wasi32::uintptr_t,
) -> wasm32::__wasi_errno_t; ) -> wasi::__wasi_errno_t;
pub unsafe fn path_readlink( pub unsafe fn path_readlink(
wasi_ctx: &WasiCtx, wasi_ctx: &WasiCtx,
memory: &mut [u8], memory: &mut [u8],
dirfd: wasm32::__wasi_fd_t, dirfd: wasi::__wasi_fd_t,
path_ptr: wasm32::uintptr_t, path_ptr: wasi32::uintptr_t,
path_len: wasm32::size_t, path_len: wasi32::size_t,
buf_ptr: wasm32::uintptr_t, buf_ptr: wasi32::uintptr_t,
buf_len: wasm32::size_t, buf_len: wasi32::size_t,
buf_used: wasm32::uintptr_t, buf_used: wasi32::uintptr_t,
) -> wasm32::__wasi_errno_t; ) -> wasi::__wasi_errno_t;
pub unsafe fn path_rename( pub unsafe fn path_rename(
wasi_ctx: &WasiCtx, wasi_ctx: &WasiCtx,
memory: &mut [u8], memory: &mut [u8],
old_dirfd: wasm32::__wasi_fd_t, old_dirfd: wasi::__wasi_fd_t,
old_path_ptr: wasm32::uintptr_t, old_path_ptr: wasi32::uintptr_t,
old_path_len: wasm32::size_t, old_path_len: wasi32::size_t,
new_dirfd: wasm32::__wasi_fd_t, new_dirfd: wasi::__wasi_fd_t,
new_path_ptr: wasm32::uintptr_t, new_path_ptr: wasi32::uintptr_t,
new_path_len: wasm32::size_t, new_path_len: wasi32::size_t,
) -> wasm32::__wasi_errno_t; ) -> wasi::__wasi_errno_t;
pub unsafe fn fd_filestat_get( pub unsafe fn fd_filestat_get(
wasi_ctx: &WasiCtx, wasi_ctx: &WasiCtx,
memory: &mut [u8], memory: &mut [u8],
fd: wasm32::__wasi_fd_t, fd: wasi::__wasi_fd_t,
filestat_ptr: wasm32::uintptr_t, filestat_ptr: wasi32::uintptr_t,
) -> wasm32::__wasi_errno_t; ) -> wasi::__wasi_errno_t;
pub unsafe fn fd_filestat_set_times( pub unsafe fn fd_filestat_set_times(
wasi_ctx: &WasiCtx, wasi_ctx: &WasiCtx,
fd: wasm32::__wasi_fd_t, fd: wasi::__wasi_fd_t,
st_atim: wasm32::__wasi_timestamp_t, st_atim: wasi::__wasi_timestamp_t,
st_mtim: wasm32::__wasi_timestamp_t, st_mtim: wasi::__wasi_timestamp_t,
fst_flags: wasm32::__wasi_fstflags_t, fst_flags: wasi::__wasi_fstflags_t,
) -> wasm32::__wasi_errno_t; ) -> wasi::__wasi_errno_t;
pub unsafe fn fd_filestat_set_size( pub unsafe fn fd_filestat_set_size(
wasi_ctx: &WasiCtx, wasi_ctx: &WasiCtx,
fd: wasm32::__wasi_fd_t, fd: wasi::__wasi_fd_t,
st_size: wasm32::__wasi_filesize_t, st_size: wasi::__wasi_filesize_t,
) -> wasm32::__wasi_errno_t; ) -> wasi::__wasi_errno_t;
pub unsafe fn path_filestat_get( pub unsafe fn path_filestat_get(
wasi_ctx: &WasiCtx, wasi_ctx: &WasiCtx,
memory: &mut [u8], memory: &mut [u8],
dirfd: wasm32::__wasi_fd_t, dirfd: wasi::__wasi_fd_t,
dirflags: wasm32::__wasi_lookupflags_t, dirflags: wasi::__wasi_lookupflags_t,
path_ptr: wasm32::uintptr_t, path_ptr: wasi32::uintptr_t,
path_len: wasm32::size_t, path_len: wasi32::size_t,
filestat_ptr: wasm32::uintptr_t, filestat_ptr: wasi32::uintptr_t,
) -> wasm32::__wasi_errno_t; ) -> wasi::__wasi_errno_t;
pub unsafe fn path_filestat_set_times( pub unsafe fn path_filestat_set_times(
wasi_ctx: &WasiCtx, wasi_ctx: &WasiCtx,
memory: &mut [u8], memory: &mut [u8],
dirfd: wasm32::__wasi_fd_t, dirfd: wasi::__wasi_fd_t,
dirflags: wasm32::__wasi_lookupflags_t, dirflags: wasi::__wasi_lookupflags_t,
path_ptr: wasm32::uintptr_t, path_ptr: wasi32::uintptr_t,
path_len: wasm32::size_t, path_len: wasi32::size_t,
st_atim: wasm32::__wasi_timestamp_t, st_atim: wasi::__wasi_timestamp_t,
st_mtim: wasm32::__wasi_timestamp_t, st_mtim: wasi::__wasi_timestamp_t,
fst_flags: wasm32::__wasi_fstflags_t, fst_flags: wasi::__wasi_fstflags_t,
) -> wasm32::__wasi_errno_t; ) -> wasi::__wasi_errno_t;
pub unsafe fn path_symlink( pub unsafe fn path_symlink(
wasi_ctx: &WasiCtx, wasi_ctx: &WasiCtx,
memory: &mut [u8], memory: &mut [u8],
old_path_ptr: wasm32::uintptr_t, old_path_ptr: wasi32::uintptr_t,
old_path_len: wasm32::size_t, old_path_len: wasi32::size_t,
dirfd: wasm32::__wasi_fd_t, dirfd: wasi::__wasi_fd_t,
new_path_ptr: wasm32::uintptr_t, new_path_ptr: wasi32::uintptr_t,
new_path_len: wasm32::size_t, new_path_len: wasi32::size_t,
) -> wasm32::__wasi_errno_t; ) -> wasi::__wasi_errno_t;
pub unsafe fn path_unlink_file( pub unsafe fn path_unlink_file(
wasi_ctx: &WasiCtx, wasi_ctx: &WasiCtx,
memory: &mut [u8], memory: &mut [u8],
dirfd: wasm32::__wasi_fd_t, dirfd: wasi::__wasi_fd_t,
path_ptr: wasm32::uintptr_t, path_ptr: wasi32::uintptr_t,
path_len: wasm32::size_t, path_len: wasi32::size_t,
) -> wasm32::__wasi_errno_t; ) -> wasi::__wasi_errno_t;
pub unsafe fn path_remove_directory( pub unsafe fn path_remove_directory(
wasi_ctx: &WasiCtx, wasi_ctx: &WasiCtx,
memory: &mut [u8], memory: &mut [u8],
dirfd: wasm32::__wasi_fd_t, dirfd: wasi::__wasi_fd_t,
path_ptr: wasm32::uintptr_t, path_ptr: wasi32::uintptr_t,
path_len: wasm32::size_t, path_len: wasi32::size_t,
) -> wasm32::__wasi_errno_t; ) -> wasi::__wasi_errno_t;
pub unsafe fn fd_prestat_get( pub unsafe fn fd_prestat_get(
wasi_ctx: &WasiCtx, wasi_ctx: &WasiCtx,
memory: &mut [u8], memory: &mut [u8],
fd: wasm32::__wasi_fd_t, fd: wasi::__wasi_fd_t,
prestat_ptr: wasm32::uintptr_t, prestat_ptr: wasi32::uintptr_t,
) -> wasm32::__wasi_errno_t; ) -> wasi::__wasi_errno_t;
pub unsafe fn fd_prestat_dir_name( pub unsafe fn fd_prestat_dir_name(
wasi_ctx: &WasiCtx, wasi_ctx: &WasiCtx,
memory: &mut [u8], memory: &mut [u8],
fd: wasm32::__wasi_fd_t, fd: wasi::__wasi_fd_t,
path_ptr: wasm32::uintptr_t, path_ptr: wasi32::uintptr_t,
path_len: wasm32::size_t, path_len: wasi32::size_t,
) -> wasm32::__wasi_errno_t; ) -> wasi::__wasi_errno_t;
} }

View File

@@ -1,25 +1,24 @@
#![allow(non_camel_case_types)] #![allow(non_camel_case_types)]
use crate::ctx::WasiCtx; use crate::ctx::WasiCtx;
use crate::memory::*; use crate::{wasi, wasi32};
use crate::wasm32;
use log::trace; use log::trace;
use wasi_common_cbindgen::wasi_common_cbindgen; use wasi_common_cbindgen::wasi_common_cbindgen;
#[wasi_common_cbindgen] #[wasi_common_cbindgen]
pub unsafe fn proc_exit(rval: wasm32::__wasi_exitcode_t) { pub unsafe fn proc_exit(rval: wasi::__wasi_exitcode_t) {
trace!("proc_exit(rval={:?})", rval); trace!("proc_exit(rval={:?})", rval);
// TODO: Rather than call std::process::exit here, we should trigger a // TODO: Rather than call std::process::exit here, we should trigger a
// stack unwind similar to a trap. // stack unwind similar to a trap.
std::process::exit(dec_exitcode(rval) as i32); std::process::exit(rval as i32);
} }
#[wasi_common_cbindgen] #[wasi_common_cbindgen]
pub unsafe fn proc_raise( pub unsafe fn proc_raise(
_wasi_ctx: &WasiCtx, _wasi_ctx: &WasiCtx,
_memory: &mut [u8], _memory: &mut [u8],
_sig: wasm32::__wasi_signal_t, _sig: wasi::__wasi_signal_t,
) -> wasm32::__wasi_errno_t { ) -> wasi::__wasi_errno_t {
unimplemented!("proc_raise") unimplemented!("proc_raise")
} }
@@ -27,58 +26,58 @@ hostcalls! {
pub unsafe fn args_get( pub unsafe fn args_get(
wasi_ctx: &WasiCtx, wasi_ctx: &WasiCtx,
memory: &mut [u8], memory: &mut [u8],
argv_ptr: wasm32::uintptr_t, argv_ptr: wasi32::uintptr_t,
argv_buf: wasm32::uintptr_t, argv_buf: wasi32::uintptr_t,
) -> wasm32::__wasi_errno_t; ) -> wasi::__wasi_errno_t;
pub unsafe fn args_sizes_get( pub unsafe fn args_sizes_get(
wasi_ctx: &WasiCtx, wasi_ctx: &WasiCtx,
memory: &mut [u8], memory: &mut [u8],
argc_ptr: wasm32::uintptr_t, argc_ptr: wasi32::uintptr_t,
argv_buf_size_ptr: wasm32::uintptr_t, argv_buf_size_ptr: wasi32::uintptr_t,
) -> wasm32::__wasi_errno_t; ) -> wasi::__wasi_errno_t;
pub unsafe fn environ_get( pub unsafe fn environ_get(
wasi_ctx: &WasiCtx, wasi_ctx: &WasiCtx,
memory: &mut [u8], memory: &mut [u8],
environ_ptr: wasm32::uintptr_t, environ_ptr: wasi32::uintptr_t,
environ_buf: wasm32::uintptr_t, environ_buf: wasi32::uintptr_t,
) -> wasm32::__wasi_errno_t; ) -> wasi::__wasi_errno_t;
pub unsafe fn environ_sizes_get( pub unsafe fn environ_sizes_get(
wasi_ctx: &WasiCtx, wasi_ctx: &WasiCtx,
memory: &mut [u8], memory: &mut [u8],
environ_count_ptr: wasm32::uintptr_t, environ_count_ptr: wasi32::uintptr_t,
environ_size_ptr: wasm32::uintptr_t, environ_size_ptr: wasi32::uintptr_t,
) -> wasm32::__wasi_errno_t; ) -> wasi::__wasi_errno_t;
pub unsafe fn random_get( pub unsafe fn random_get(
memory: &mut [u8], memory: &mut [u8],
buf_ptr: wasm32::uintptr_t, buf_ptr: wasi32::uintptr_t,
buf_len: wasm32::size_t, buf_len: wasi32::size_t,
) -> wasm32::__wasi_errno_t; ) -> wasi::__wasi_errno_t;
pub unsafe fn clock_res_get( pub unsafe fn clock_res_get(
memory: &mut [u8], memory: &mut [u8],
clock_id: wasm32::__wasi_clockid_t, clock_id: wasi::__wasi_clockid_t,
resolution_ptr: wasm32::uintptr_t, resolution_ptr: wasi32::uintptr_t,
) -> wasm32::__wasi_errno_t; ) -> wasi::__wasi_errno_t;
pub unsafe fn clock_time_get( pub unsafe fn clock_time_get(
memory: &mut [u8], memory: &mut [u8],
clock_id: wasm32::__wasi_clockid_t, clock_id: wasi::__wasi_clockid_t,
precision: wasm32::__wasi_timestamp_t, precision: wasi::__wasi_timestamp_t,
time_ptr: wasm32::uintptr_t, time_ptr: wasi32::uintptr_t,
) -> wasm32::__wasi_errno_t; ) -> wasi::__wasi_errno_t;
pub unsafe fn poll_oneoff( pub unsafe fn poll_oneoff(
wasi_ctx: &WasiCtx, wasi_ctx: &WasiCtx,
memory: &mut [u8], memory: &mut [u8],
input: wasm32::uintptr_t, input: wasi32::uintptr_t,
output: wasm32::uintptr_t, output: wasi32::uintptr_t,
nsubscriptions: wasm32::size_t, nsubscriptions: wasi32::size_t,
nevents: wasm32::uintptr_t, nevents: wasi32::uintptr_t,
) -> wasm32::__wasi_errno_t; ) -> wasi::__wasi_errno_t;
pub unsafe fn sched_yield() -> wasm32::__wasi_errno_t; pub unsafe fn sched_yield() -> wasi::__wasi_errno_t;
} }

View File

@@ -5,11 +5,3 @@ mod sock;
pub use self::fs::*; pub use self::fs::*;
pub use self::misc::*; pub use self::misc::*;
pub use self::sock::*; pub use self::sock::*;
use crate::{host, memory, wasm32};
fn return_enc_errno(errno: host::__wasi_errno_t) -> wasm32::__wasi_errno_t {
let errno = memory::enc_errno(errno);
log::trace!(" -> errno={}", wasm32::strerror(errno));
errno
}

View File

@@ -2,20 +2,20 @@
#![allow(unused_unsafe)] #![allow(unused_unsafe)]
#![allow(unused)] #![allow(unused)]
use crate::ctx::WasiCtx; use crate::ctx::WasiCtx;
use crate::wasm32; use crate::{wasi, wasi32};
use wasi_common_cbindgen::wasi_common_cbindgen; use wasi_common_cbindgen::wasi_common_cbindgen;
#[wasi_common_cbindgen] #[wasi_common_cbindgen]
pub unsafe fn sock_recv( pub unsafe fn sock_recv(
wasi_ctx: &WasiCtx, wasi_ctx: &WasiCtx,
memory: &mut [u8], memory: &mut [u8],
sock: wasm32::__wasi_fd_t, sock: wasi::__wasi_fd_t,
ri_data: wasm32::uintptr_t, ri_data: wasi32::uintptr_t,
ri_data_len: wasm32::size_t, ri_data_len: wasi32::size_t,
ri_flags: wasm32::__wasi_riflags_t, ri_flags: wasi::__wasi_riflags_t,
ro_datalen: wasm32::uintptr_t, ro_datalen: wasi32::uintptr_t,
ro_flags: wasm32::uintptr_t, ro_flags: wasi32::uintptr_t,
) -> wasm32::__wasi_errno_t { ) -> wasi::__wasi_errno_t {
unimplemented!("sock_recv") unimplemented!("sock_recv")
} }
@@ -23,12 +23,12 @@ pub unsafe fn sock_recv(
pub unsafe fn sock_send( pub unsafe fn sock_send(
wasi_ctx: &WasiCtx, wasi_ctx: &WasiCtx,
memory: &mut [u8], memory: &mut [u8],
sock: wasm32::__wasi_fd_t, sock: wasi::__wasi_fd_t,
si_data: wasm32::uintptr_t, si_data: wasi32::uintptr_t,
si_data_len: wasm32::size_t, si_data_len: wasi32::size_t,
si_flags: wasm32::__wasi_siflags_t, si_flags: wasi::__wasi_siflags_t,
so_datalen: wasm32::uintptr_t, so_datalen: wasi32::uintptr_t,
) -> wasm32::__wasi_errno_t { ) -> wasi::__wasi_errno_t {
unimplemented!("sock_send") unimplemented!("sock_send")
} }
@@ -36,8 +36,8 @@ pub unsafe fn sock_send(
pub unsafe fn sock_shutdown( pub unsafe fn sock_shutdown(
wasi_ctx: &WasiCtx, wasi_ctx: &WasiCtx,
memory: &mut [u8], memory: &mut [u8],
sock: wasm32::__wasi_fd_t, sock: wasi::__wasi_fd_t,
how: wasm32::__wasi_sdflags_t, how: wasi::__wasi_sdflags_t,
) -> wasm32::__wasi_errno_t { ) -> wasi::__wasi_errno_t {
unimplemented!("sock_shutdown") unimplemented!("sock_shutdown")
} }

View File

@@ -2,21 +2,21 @@
use super::fs_helpers::path_get; use super::fs_helpers::path_get;
use crate::ctx::WasiCtx; use crate::ctx::WasiCtx;
use crate::fdentry::{Descriptor, FdEntry}; use crate::fdentry::{Descriptor, FdEntry};
use crate::helpers::*;
use crate::memory::*; use crate::memory::*;
use crate::sys::fdentry_impl::determine_type_rights; use crate::sys::fdentry_impl::determine_type_rights;
use crate::sys::hostcalls_impl::fs_helpers::path_open_rights; use crate::sys::hostcalls_impl::fs_helpers::path_open_rights;
use crate::sys::{host_impl, hostcalls_impl}; use crate::sys::{host_impl, hostcalls_impl};
use crate::{host, wasm32, Error, Result}; use crate::{helpers, host, wasi, wasi32, Error, Result};
use filetime::{set_file_handle_times, FileTime}; use filetime::{set_file_handle_times, FileTime};
use log::trace; use log::trace;
use std::fs::File; use std::fs::File;
use std::io::{self, Read, Seek, SeekFrom, Write}; use std::io::{self, Read, Seek, SeekFrom, Write};
use std::time::{Duration, SystemTime, UNIX_EPOCH}; use std::time::{Duration, SystemTime, UNIX_EPOCH};
pub(crate) unsafe fn fd_close(wasi_ctx: &mut WasiCtx, fd: wasm32::__wasi_fd_t) -> Result<()> { pub(crate) unsafe fn fd_close(wasi_ctx: &mut WasiCtx, fd: wasi::__wasi_fd_t) -> Result<()> {
trace!("fd_close(fd={:?})", fd); trace!("fd_close(fd={:?})", fd);
let fd = dec_fd(fd);
if let Ok(fe) = wasi_ctx.get_fd_entry(fd) { if let Ok(fe) = wasi_ctx.get_fd_entry(fd) {
// can't close preopened files // can't close preopened files
if fe.preopen_path.is_some() { if fe.preopen_path.is_some() {
@@ -28,13 +28,12 @@ pub(crate) unsafe fn fd_close(wasi_ctx: &mut WasiCtx, fd: wasm32::__wasi_fd_t) -
Ok(()) Ok(())
} }
pub(crate) unsafe fn fd_datasync(wasi_ctx: &WasiCtx, fd: wasm32::__wasi_fd_t) -> Result<()> { pub(crate) unsafe fn fd_datasync(wasi_ctx: &WasiCtx, fd: wasi::__wasi_fd_t) -> Result<()> {
trace!("fd_datasync(fd={:?})", fd); trace!("fd_datasync(fd={:?})", fd);
let fd = dec_fd(fd);
let fd = wasi_ctx let fd = wasi_ctx
.get_fd_entry(fd)? .get_fd_entry(fd)?
.as_descriptor(host::__WASI_RIGHT_FD_DATASYNC, 0)? .as_descriptor(wasi::__WASI_RIGHT_FD_DATASYNC, 0)?
.as_file()?; .as_file()?;
fd.sync_data().map_err(Into::into) fd.sync_data().map_err(Into::into)
@@ -43,11 +42,11 @@ pub(crate) unsafe fn fd_datasync(wasi_ctx: &WasiCtx, fd: wasm32::__wasi_fd_t) ->
pub(crate) unsafe fn fd_pread( pub(crate) unsafe fn fd_pread(
wasi_ctx: &WasiCtx, wasi_ctx: &WasiCtx,
memory: &mut [u8], memory: &mut [u8],
fd: wasm32::__wasi_fd_t, fd: wasi::__wasi_fd_t,
iovs_ptr: wasm32::uintptr_t, iovs_ptr: wasi32::uintptr_t,
iovs_len: wasm32::size_t, iovs_len: wasi32::size_t,
offset: wasm32::__wasi_filesize_t, offset: wasi::__wasi_filesize_t,
nread: wasm32::uintptr_t, nread: wasi32::uintptr_t,
) -> Result<()> { ) -> Result<()> {
trace!( trace!(
"fd_pread(fd={:?}, iovs_ptr={:#x?}, iovs_len={:?}, offset={}, nread={:#x?})", "fd_pread(fd={:?}, iovs_ptr={:#x?}, iovs_len={:?}, offset={}, nread={:#x?})",
@@ -58,15 +57,13 @@ pub(crate) unsafe fn fd_pread(
nread nread
); );
let fd = dec_fd(fd);
let fd = wasi_ctx let fd = wasi_ctx
.get_fd_entry(fd)? .get_fd_entry(fd)?
.as_descriptor(host::__WASI_RIGHT_FD_READ, 0)? .as_descriptor(wasi::__WASI_RIGHT_FD_READ, 0)?
.as_file()?; .as_file()?;
let iovs = dec_iovec_slice(memory, iovs_ptr, iovs_len)?; let iovs = dec_iovec_slice(memory, iovs_ptr, iovs_len)?;
let offset = dec_filesize(offset);
if offset > i64::max_value() as u64 { if offset > i64::max_value() as u64 {
return Err(Error::EIO); return Err(Error::EIO);
} }
@@ -94,11 +91,11 @@ pub(crate) unsafe fn fd_pread(
pub(crate) unsafe fn fd_pwrite( pub(crate) unsafe fn fd_pwrite(
wasi_ctx: &WasiCtx, wasi_ctx: &WasiCtx,
memory: &mut [u8], memory: &mut [u8],
fd: wasm32::__wasi_fd_t, fd: wasi::__wasi_fd_t,
iovs_ptr: wasm32::uintptr_t, iovs_ptr: wasi32::uintptr_t,
iovs_len: wasm32::size_t, iovs_len: wasi32::size_t,
offset: wasm32::__wasi_filesize_t, offset: wasi::__wasi_filesize_t,
nwritten: wasm32::uintptr_t, nwritten: wasi32::uintptr_t,
) -> Result<()> { ) -> Result<()> {
trace!( trace!(
"fd_pwrite(fd={:?}, iovs_ptr={:#x?}, iovs_len={:?}, offset={}, nwritten={:#x?})", "fd_pwrite(fd={:?}, iovs_ptr={:#x?}, iovs_len={:?}, offset={}, nwritten={:#x?})",
@@ -109,14 +106,12 @@ pub(crate) unsafe fn fd_pwrite(
nwritten nwritten
); );
let fd = dec_fd(fd);
let fd = wasi_ctx let fd = wasi_ctx
.get_fd_entry(fd)? .get_fd_entry(fd)?
.as_descriptor(host::__WASI_RIGHT_FD_READ, 0)? .as_descriptor(wasi::__WASI_RIGHT_FD_READ, 0)?
.as_file()?; .as_file()?;
let iovs = dec_iovec_slice(memory, iovs_ptr, iovs_len)?; let iovs = dec_iovec_slice(memory, iovs_ptr, iovs_len)?;
let offset = dec_filesize(offset);
if offset > i64::max_value() as u64 { if offset > i64::max_value() as u64 {
return Err(Error::EIO); return Err(Error::EIO);
} }
@@ -138,10 +133,10 @@ pub(crate) unsafe fn fd_pwrite(
pub(crate) unsafe fn fd_read( pub(crate) unsafe fn fd_read(
wasi_ctx: &mut WasiCtx, wasi_ctx: &mut WasiCtx,
memory: &mut [u8], memory: &mut [u8],
fd: wasm32::__wasi_fd_t, fd: wasi::__wasi_fd_t,
iovs_ptr: wasm32::uintptr_t, iovs_ptr: wasi32::uintptr_t,
iovs_len: wasm32::size_t, iovs_len: wasi32::size_t,
nread: wasm32::uintptr_t, nread: wasi32::uintptr_t,
) -> Result<()> { ) -> Result<()> {
trace!( trace!(
"fd_read(fd={:?}, iovs_ptr={:#x?}, iovs_len={:?}, nread={:#x?})", "fd_read(fd={:?}, iovs_ptr={:#x?}, iovs_len={:?}, nread={:#x?})",
@@ -156,11 +151,10 @@ pub(crate) unsafe fn fd_read(
.iter_mut() .iter_mut()
.map(|vec| host::iovec_to_host_mut(vec)) .map(|vec| host::iovec_to_host_mut(vec))
.collect(); .collect();
let fd = dec_fd(fd);
let maybe_host_nread = match wasi_ctx let maybe_host_nread = match wasi_ctx
.get_fd_entry_mut(fd)? .get_fd_entry_mut(fd)?
.as_descriptor_mut(host::__WASI_RIGHT_FD_READ, 0)? .as_descriptor_mut(wasi::__WASI_RIGHT_FD_READ, 0)?
{ {
Descriptor::OsFile(file) => file.read_vectored(&mut iovs), Descriptor::OsFile(file) => file.read_vectored(&mut iovs),
Descriptor::Stdin => io::stdin().lock().read_vectored(&mut iovs), Descriptor::Stdin => io::stdin().lock().read_vectored(&mut iovs),
@@ -176,14 +170,11 @@ pub(crate) unsafe fn fd_read(
pub(crate) unsafe fn fd_renumber( pub(crate) unsafe fn fd_renumber(
wasi_ctx: &mut WasiCtx, wasi_ctx: &mut WasiCtx,
from: wasm32::__wasi_fd_t, from: wasi::__wasi_fd_t,
to: wasm32::__wasi_fd_t, to: wasi::__wasi_fd_t,
) -> Result<()> { ) -> Result<()> {
trace!("fd_renumber(from={:?}, to={:?})", from, to); trace!("fd_renumber(from={:?}, to={:?})", from, to);
let from = dec_fd(from);
let to = dec_fd(to);
if !wasi_ctx.contains_fd_entry(from) || !wasi_ctx.contains_fd_entry(to) { if !wasi_ctx.contains_fd_entry(from) || !wasi_ctx.contains_fd_entry(to) {
return Err(Error::EBADF); return Err(Error::EBADF);
} }
@@ -218,27 +209,23 @@ pub(crate) unsafe fn fd_renumber(
pub(crate) unsafe fn fd_seek( pub(crate) unsafe fn fd_seek(
wasi_ctx: &mut WasiCtx, wasi_ctx: &mut WasiCtx,
memory: &mut [u8], memory: &mut [u8],
fd: wasm32::__wasi_fd_t, fd: wasi::__wasi_fd_t,
offset: wasm32::__wasi_filedelta_t, offset: wasi::__wasi_filedelta_t,
whence: wasm32::__wasi_whence_t, whence: wasi::__wasi_whence_t,
newoffset: wasm32::uintptr_t, newoffset: wasi32::uintptr_t,
) -> Result<()> { ) -> Result<()> {
trace!( trace!(
"fd_seek(fd={:?}, offset={:?}, whence={}, newoffset={:#x?})", "fd_seek(fd={:?}, offset={:?}, whence={}, newoffset={:#x?})",
fd, fd,
offset, offset,
wasm32::whence_to_str(whence), wasi::whence_to_str(whence),
newoffset newoffset
); );
let fd = dec_fd(fd); let rights = if offset == 0 && whence == wasi::__WASI_WHENCE_CUR {
let offset = dec_filedelta(offset); wasi::__WASI_RIGHT_FD_TELL
let whence = dec_whence(whence);
let rights = if offset == 0 && whence == host::__WASI_WHENCE_CUR {
host::__WASI_RIGHT_FD_TELL
} else { } else {
host::__WASI_RIGHT_FD_SEEK | host::__WASI_RIGHT_FD_TELL wasi::__WASI_RIGHT_FD_SEEK | wasi::__WASI_RIGHT_FD_TELL
}; };
let fd = wasi_ctx let fd = wasi_ctx
.get_fd_entry_mut(fd)? .get_fd_entry_mut(fd)?
@@ -246,9 +233,9 @@ pub(crate) unsafe fn fd_seek(
.as_file_mut()?; .as_file_mut()?;
let pos = match whence { let pos = match whence {
host::__WASI_WHENCE_CUR => SeekFrom::Current(offset), wasi::__WASI_WHENCE_CUR => SeekFrom::Current(offset),
host::__WASI_WHENCE_END => SeekFrom::End(offset), wasi::__WASI_WHENCE_END => SeekFrom::End(offset),
host::__WASI_WHENCE_SET => SeekFrom::Start(offset as u64), wasi::__WASI_WHENCE_SET => SeekFrom::Start(offset as u64),
_ => return Err(Error::EINVAL), _ => return Err(Error::EINVAL),
}; };
let host_newoffset = fd.seek(pos)?; let host_newoffset = fd.seek(pos)?;
@@ -261,15 +248,14 @@ pub(crate) unsafe fn fd_seek(
pub(crate) unsafe fn fd_tell( pub(crate) unsafe fn fd_tell(
wasi_ctx: &mut WasiCtx, wasi_ctx: &mut WasiCtx,
memory: &mut [u8], memory: &mut [u8],
fd: wasm32::__wasi_fd_t, fd: wasi::__wasi_fd_t,
newoffset: wasm32::uintptr_t, newoffset: wasi32::uintptr_t,
) -> Result<()> { ) -> Result<()> {
trace!("fd_tell(fd={:?}, newoffset={:#x?})", fd, newoffset); trace!("fd_tell(fd={:?}, newoffset={:#x?})", fd, newoffset);
let fd = dec_fd(fd);
let fd = wasi_ctx let fd = wasi_ctx
.get_fd_entry_mut(fd)? .get_fd_entry_mut(fd)?
.as_descriptor_mut(host::__WASI_RIGHT_FD_TELL, 0)? .as_descriptor_mut(wasi::__WASI_RIGHT_FD_TELL, 0)?
.as_file_mut()?; .as_file_mut()?;
let host_offset = fd.seek(SeekFrom::Current(0))?; let host_offset = fd.seek(SeekFrom::Current(0))?;
@@ -282,13 +268,12 @@ pub(crate) unsafe fn fd_tell(
pub(crate) unsafe fn fd_fdstat_get( pub(crate) unsafe fn fd_fdstat_get(
wasi_ctx: &WasiCtx, wasi_ctx: &WasiCtx,
memory: &mut [u8], memory: &mut [u8],
fd: wasm32::__wasi_fd_t, fd: wasi::__wasi_fd_t,
fdstat_ptr: wasm32::uintptr_t, // *mut wasm32::__wasi_fdstat_t fdstat_ptr: wasi32::uintptr_t, // *mut wasi::__wasi_fdstat_t
) -> Result<()> { ) -> Result<()> {
trace!("fd_fdstat_get(fd={:?}, fdstat_ptr={:#x?})", fd, fdstat_ptr); trace!("fd_fdstat_get(fd={:?}, fdstat_ptr={:#x?})", fd, fdstat_ptr);
let mut fdstat = dec_fdstat_byref(memory, fdstat_ptr)?; let mut fdstat = dec_fdstat_byref(memory, fdstat_ptr)?;
let fd = dec_fd(fd);
let wasi_fd = wasi_ctx.get_fd_entry(fd)?.as_descriptor(0, 0)?.as_file()?; let wasi_fd = wasi_ctx.get_fd_entry(fd)?.as_descriptor(0, 0)?.as_file()?;
let fs_flags = hostcalls_impl::fd_fdstat_get(wasi_fd)?; let fs_flags = hostcalls_impl::fd_fdstat_get(wasi_fd)?;
@@ -306,13 +291,11 @@ pub(crate) unsafe fn fd_fdstat_get(
pub(crate) unsafe fn fd_fdstat_set_flags( pub(crate) unsafe fn fd_fdstat_set_flags(
wasi_ctx: &WasiCtx, wasi_ctx: &WasiCtx,
fd: wasm32::__wasi_fd_t, fd: wasi::__wasi_fd_t,
fdflags: wasm32::__wasi_fdflags_t, fdflags: wasi::__wasi_fdflags_t,
) -> Result<()> { ) -> Result<()> {
trace!("fd_fdstat_set_flags(fd={:?}, fdflags={:#x?})", fd, fdflags); trace!("fd_fdstat_set_flags(fd={:?}, fdflags={:#x?})", fd, fdflags);
let fdflags = dec_fdflags(fdflags);
let fd = dec_fd(fd);
let fd = wasi_ctx.get_fd_entry(fd)?.as_descriptor(0, 0)?.as_file()?; let fd = wasi_ctx.get_fd_entry(fd)?.as_descriptor(0, 0)?.as_file()?;
hostcalls_impl::fd_fdstat_set_flags(fd, fdflags) hostcalls_impl::fd_fdstat_set_flags(fd, fdflags)
@@ -320,9 +303,9 @@ pub(crate) unsafe fn fd_fdstat_set_flags(
pub(crate) unsafe fn fd_fdstat_set_rights( pub(crate) unsafe fn fd_fdstat_set_rights(
wasi_ctx: &mut WasiCtx, wasi_ctx: &mut WasiCtx,
fd: wasm32::__wasi_fd_t, fd: wasi::__wasi_fd_t,
fs_rights_base: wasm32::__wasi_rights_t, fs_rights_base: wasi::__wasi_rights_t,
fs_rights_inheriting: wasm32::__wasi_rights_t, fs_rights_inheriting: wasi::__wasi_rights_t,
) -> Result<()> { ) -> Result<()> {
trace!( trace!(
"fd_fdstat_set_rights(fd={:?}, fs_rights_base={:#x?}, fs_rights_inheriting={:#x?})", "fd_fdstat_set_rights(fd={:?}, fs_rights_base={:#x?}, fs_rights_inheriting={:#x?})",
@@ -331,7 +314,6 @@ pub(crate) unsafe fn fd_fdstat_set_rights(
fs_rights_inheriting fs_rights_inheriting
); );
let fd = dec_fd(fd);
let fe = &mut wasi_ctx.get_fd_entry_mut(fd)?; let fe = &mut wasi_ctx.get_fd_entry_mut(fd)?;
if fe.rights_base & fs_rights_base != fs_rights_base if fe.rights_base & fs_rights_base != fs_rights_base
@@ -345,13 +327,12 @@ pub(crate) unsafe fn fd_fdstat_set_rights(
Ok(()) Ok(())
} }
pub(crate) unsafe fn fd_sync(wasi_ctx: &WasiCtx, fd: wasm32::__wasi_fd_t) -> Result<()> { pub(crate) unsafe fn fd_sync(wasi_ctx: &WasiCtx, fd: wasi::__wasi_fd_t) -> Result<()> {
trace!("fd_sync(fd={:?})", fd); trace!("fd_sync(fd={:?})", fd);
let fd = dec_fd(fd);
let fd = wasi_ctx let fd = wasi_ctx
.get_fd_entry(fd)? .get_fd_entry(fd)?
.as_descriptor(host::__WASI_RIGHT_FD_SYNC, 0)? .as_descriptor(wasi::__WASI_RIGHT_FD_SYNC, 0)?
.as_file()?; .as_file()?;
fd.sync_all().map_err(Into::into) fd.sync_all().map_err(Into::into)
} }
@@ -359,10 +340,10 @@ pub(crate) unsafe fn fd_sync(wasi_ctx: &WasiCtx, fd: wasm32::__wasi_fd_t) -> Res
pub(crate) unsafe fn fd_write( pub(crate) unsafe fn fd_write(
wasi_ctx: &mut WasiCtx, wasi_ctx: &mut WasiCtx,
memory: &mut [u8], memory: &mut [u8],
fd: wasm32::__wasi_fd_t, fd: wasi::__wasi_fd_t,
iovs_ptr: wasm32::uintptr_t, iovs_ptr: wasi32::uintptr_t,
iovs_len: wasm32::size_t, iovs_len: wasi32::size_t,
nwritten: wasm32::uintptr_t, nwritten: wasi32::uintptr_t,
) -> Result<()> { ) -> Result<()> {
trace!( trace!(
"fd_write(fd={:?}, iovs_ptr={:#x?}, iovs_len={:?}, nwritten={:#x?})", "fd_write(fd={:?}, iovs_ptr={:#x?}, iovs_len={:?}, nwritten={:#x?})",
@@ -372,14 +353,13 @@ pub(crate) unsafe fn fd_write(
nwritten nwritten
); );
let fd = dec_fd(fd);
let iovs = dec_iovec_slice(memory, iovs_ptr, iovs_len)?; let iovs = dec_iovec_slice(memory, iovs_ptr, iovs_len)?;
let iovs: Vec<io::IoSlice> = iovs.iter().map(|vec| host::iovec_to_host(vec)).collect(); let iovs: Vec<io::IoSlice> = iovs.iter().map(|vec| host::iovec_to_host(vec)).collect();
// perform unbuffered writes // perform unbuffered writes
let host_nwritten = match wasi_ctx let host_nwritten = match wasi_ctx
.get_fd_entry_mut(fd)? .get_fd_entry_mut(fd)?
.as_descriptor_mut(host::__WASI_RIGHT_FD_WRITE, 0)? .as_descriptor_mut(wasi::__WASI_RIGHT_FD_WRITE, 0)?
{ {
Descriptor::OsFile(file) => file.write_vectored(&iovs)?, Descriptor::OsFile(file) => file.write_vectored(&iovs)?,
Descriptor::Stdin => return Err(Error::EBADF), Descriptor::Stdin => return Err(Error::EBADF),
@@ -401,10 +381,10 @@ pub(crate) unsafe fn fd_write(
pub(crate) unsafe fn fd_advise( pub(crate) unsafe fn fd_advise(
wasi_ctx: &WasiCtx, wasi_ctx: &WasiCtx,
fd: wasm32::__wasi_fd_t, fd: wasi::__wasi_fd_t,
offset: wasm32::__wasi_filesize_t, offset: wasi::__wasi_filesize_t,
len: wasm32::__wasi_filesize_t, len: wasi::__wasi_filesize_t,
advice: wasm32::__wasi_advice_t, advice: wasi::__wasi_advice_t,
) -> Result<()> { ) -> Result<()> {
trace!( trace!(
"fd_advise(fd={:?}, offset={}, len={}, advice={:?})", "fd_advise(fd={:?}, offset={}, len={}, advice={:?})",
@@ -414,13 +394,9 @@ pub(crate) unsafe fn fd_advise(
advice advice
); );
let fd = dec_fd(fd);
let advice = dec_advice(advice);
let offset = dec_filesize(offset);
let len = dec_filesize(len);
let fd = wasi_ctx let fd = wasi_ctx
.get_fd_entry(fd)? .get_fd_entry(fd)?
.as_descriptor(host::__WASI_RIGHT_FD_ADVISE, 0)? .as_descriptor(wasi::__WASI_RIGHT_FD_ADVISE, 0)?
.as_file()?; .as_file()?;
hostcalls_impl::fd_advise(fd, advice, offset, len) hostcalls_impl::fd_advise(fd, advice, offset, len)
@@ -428,18 +404,15 @@ pub(crate) unsafe fn fd_advise(
pub(crate) unsafe fn fd_allocate( pub(crate) unsafe fn fd_allocate(
wasi_ctx: &WasiCtx, wasi_ctx: &WasiCtx,
fd: wasm32::__wasi_fd_t, fd: wasi::__wasi_fd_t,
offset: wasm32::__wasi_filesize_t, offset: wasi::__wasi_filesize_t,
len: wasm32::__wasi_filesize_t, len: wasi::__wasi_filesize_t,
) -> Result<()> { ) -> Result<()> {
trace!("fd_allocate(fd={:?}, offset={}, len={})", fd, offset, len); trace!("fd_allocate(fd={:?}, offset={}, len={})", fd, offset, len);
let fd = dec_fd(fd);
let offset = dec_filesize(offset);
let len = dec_filesize(len);
let fd = wasi_ctx let fd = wasi_ctx
.get_fd_entry(fd)? .get_fd_entry(fd)?
.as_descriptor(host::__WASI_RIGHT_FD_ALLOCATE, 0)? .as_descriptor(wasi::__WASI_RIGHT_FD_ALLOCATE, 0)?
.as_file()?; .as_file()?;
let metadata = fd.metadata()?; let metadata = fd.metadata()?;
@@ -461,9 +434,9 @@ pub(crate) unsafe fn fd_allocate(
pub(crate) unsafe fn path_create_directory( pub(crate) unsafe fn path_create_directory(
wasi_ctx: &WasiCtx, wasi_ctx: &WasiCtx,
memory: &mut [u8], memory: &mut [u8],
dirfd: wasm32::__wasi_fd_t, dirfd: wasi::__wasi_fd_t,
path_ptr: wasm32::uintptr_t, path_ptr: wasi32::uintptr_t,
path_len: wasm32::size_t, path_len: wasi32::size_t,
) -> Result<()> { ) -> Result<()> {
trace!( trace!(
"path_create_directory(dirfd={:?}, path_ptr={:#x?}, path_len={})", "path_create_directory(dirfd={:?}, path_ptr={:#x?}, path_len={})",
@@ -472,12 +445,11 @@ pub(crate) unsafe fn path_create_directory(
path_len, path_len,
); );
let dirfd = dec_fd(dirfd); let path = dec_slice_of_u8(memory, path_ptr, path_len).and_then(helpers::path_from_slice)?;
let path = dec_slice_of::<u8>(memory, path_ptr, path_len).and_then(host::path_from_slice)?;
trace!(" | (path_ptr,path_len)='{}'", path); trace!(" | (path_ptr,path_len)='{}'", path);
let rights = host::__WASI_RIGHT_PATH_OPEN | host::__WASI_RIGHT_PATH_CREATE_DIRECTORY; let rights = wasi::__WASI_RIGHT_PATH_OPEN | wasi::__WASI_RIGHT_PATH_CREATE_DIRECTORY;
let fe = &wasi_ctx.get_fd_entry(dirfd)?; let fe = &wasi_ctx.get_fd_entry(dirfd)?;
let resolved = path_get(fe, rights, 0, 0, path, false)?; let resolved = path_get(fe, rights, 0, 0, path, false)?;
@@ -487,13 +459,13 @@ pub(crate) unsafe fn path_create_directory(
pub(crate) unsafe fn path_link( pub(crate) unsafe fn path_link(
wasi_ctx: &WasiCtx, wasi_ctx: &WasiCtx,
memory: &mut [u8], memory: &mut [u8],
old_dirfd: wasm32::__wasi_fd_t, old_dirfd: wasi::__wasi_fd_t,
old_flags: wasm32::__wasi_lookupflags_t, old_flags: wasi::__wasi_lookupflags_t,
old_path_ptr: wasm32::uintptr_t, old_path_ptr: wasi32::uintptr_t,
old_path_len: wasm32::size_t, old_path_len: wasi32::size_t,
new_dirfd: wasm32::__wasi_fd_t, new_dirfd: wasi::__wasi_fd_t,
new_path_ptr: wasm32::uintptr_t, new_path_ptr: wasi32::uintptr_t,
new_path_len: wasm32::size_t, new_path_len: wasi32::size_t,
) -> Result<()> { ) -> Result<()> {
trace!( trace!(
"path_link(old_dirfd={:?}, old_flags={:?}, old_path_ptr={:#x?}, old_path_len={}, new_dirfd={:?}, new_path_ptr={:#x?}, new_path_len={})", "path_link(old_dirfd={:?}, old_flags={:?}, old_path_ptr={:#x?}, old_path_len={}, new_dirfd={:?}, new_path_ptr={:#x?}, new_path_len={})",
@@ -506,12 +478,8 @@ pub(crate) unsafe fn path_link(
new_path_len, new_path_len,
); );
let old_dirfd = dec_fd(old_dirfd); let old_path = dec_slice_of_u8(memory, old_path_ptr, old_path_len).and_then(path_from_slice)?;
let new_dirfd = dec_fd(new_dirfd); let new_path = dec_slice_of_u8(memory, new_path_ptr, new_path_len).and_then(path_from_slice)?;
let old_path =
dec_slice_of::<u8>(memory, old_path_ptr, old_path_len).and_then(host::path_from_slice)?;
let new_path =
dec_slice_of::<u8>(memory, new_path_ptr, new_path_len).and_then(host::path_from_slice)?;
trace!(" | (old_path_ptr,old_path_len)='{}'", old_path); trace!(" | (old_path_ptr,old_path_len)='{}'", old_path);
trace!(" | (new_path_ptr,new_path_len)='{}'", new_path); trace!(" | (new_path_ptr,new_path_len)='{}'", new_path);
@@ -520,7 +488,7 @@ pub(crate) unsafe fn path_link(
let new_fe = &wasi_ctx.get_fd_entry(new_dirfd)?; let new_fe = &wasi_ctx.get_fd_entry(new_dirfd)?;
let resolved_old = path_get( let resolved_old = path_get(
old_fe, old_fe,
host::__WASI_RIGHT_PATH_LINK_SOURCE, wasi::__WASI_RIGHT_PATH_LINK_SOURCE,
0, 0,
0, 0,
old_path, old_path,
@@ -528,7 +496,7 @@ pub(crate) unsafe fn path_link(
)?; )?;
let resolved_new = path_get( let resolved_new = path_get(
new_fe, new_fe,
host::__WASI_RIGHT_PATH_LINK_TARGET, wasi::__WASI_RIGHT_PATH_LINK_TARGET,
0, 0,
0, 0,
new_path, new_path,
@@ -541,15 +509,15 @@ pub(crate) unsafe fn path_link(
pub(crate) unsafe fn path_open( pub(crate) unsafe fn path_open(
wasi_ctx: &mut WasiCtx, wasi_ctx: &mut WasiCtx,
memory: &mut [u8], memory: &mut [u8],
dirfd: wasm32::__wasi_fd_t, dirfd: wasi::__wasi_fd_t,
dirflags: wasm32::__wasi_lookupflags_t, dirflags: wasi::__wasi_lookupflags_t,
path_ptr: wasm32::uintptr_t, path_ptr: wasi32::uintptr_t,
path_len: wasm32::size_t, path_len: wasi32::size_t,
oflags: wasm32::__wasi_oflags_t, oflags: wasi::__wasi_oflags_t,
fs_rights_base: wasm32::__wasi_rights_t, fs_rights_base: wasi::__wasi_rights_t,
fs_rights_inheriting: wasm32::__wasi_rights_t, fs_rights_inheriting: wasi::__wasi_rights_t,
fs_flags: wasm32::__wasi_fdflags_t, fs_flags: wasi::__wasi_fdflags_t,
fd_out_ptr: wasm32::uintptr_t, fd_out_ptr: wasi32::uintptr_t,
) -> Result<()> { ) -> Result<()> {
trace!( trace!(
"path_open(dirfd={:?}, dirflags={:?}, path_ptr={:#x?}, path_len={:?}, oflags={:#x?}, fs_rights_base={:#x?}, fs_rights_inheriting={:#x?}, fs_flags={:#x?}, fd_out_ptr={:#x?})", "path_open(dirfd={:?}, dirflags={:?}, path_ptr={:#x?}, path_len={:?}, oflags={:#x?}, fs_rights_base={:#x?}, fs_rights_inheriting={:#x?}, fs_flags={:#x?}, fd_out_ptr={:#x?})",
@@ -565,16 +533,9 @@ pub(crate) unsafe fn path_open(
); );
// pre-encode fd_out_ptr to -1 in case of error in opening a path // pre-encode fd_out_ptr to -1 in case of error in opening a path
enc_fd_byref(memory, fd_out_ptr, wasm32::__wasi_fd_t::max_value())?; enc_fd_byref(memory, fd_out_ptr, wasi::__wasi_fd_t::max_value())?;
let dirfd = dec_fd(dirfd); let path = dec_slice_of_u8(memory, path_ptr, path_len).and_then(path_from_slice)?;
let dirflags = dec_lookupflags(dirflags);
let oflags = dec_oflags(oflags);
let fs_rights_base = dec_rights(fs_rights_base);
let fs_rights_inheriting = dec_rights(fs_rights_inheriting);
let fs_flags = dec_fdflags(fs_flags);
let path = dec_slice_of::<u8>(memory, path_ptr, path_len).and_then(host::path_from_slice)?;
trace!(" | (path_ptr,path_len)='{}'", path); trace!(" | (path_ptr,path_len)='{}'", path);
@@ -587,16 +548,16 @@ pub(crate) unsafe fn path_open(
needed_inheriting, needed_inheriting,
dirflags, dirflags,
path, path,
oflags & host::__WASI_O_CREAT != 0, oflags & wasi::__WASI_O_CREAT != 0,
)?; )?;
// which open mode do we need? // which open mode do we need?
let read = fs_rights_base & (host::__WASI_RIGHT_FD_READ | host::__WASI_RIGHT_FD_READDIR) != 0; let read = fs_rights_base & (wasi::__WASI_RIGHT_FD_READ | wasi::__WASI_RIGHT_FD_READDIR) != 0;
let write = fs_rights_base let write = fs_rights_base
& (host::__WASI_RIGHT_FD_DATASYNC & (wasi::__WASI_RIGHT_FD_DATASYNC
| host::__WASI_RIGHT_FD_WRITE | wasi::__WASI_RIGHT_FD_WRITE
| host::__WASI_RIGHT_FD_ALLOCATE | wasi::__WASI_RIGHT_FD_ALLOCATE
| host::__WASI_RIGHT_FD_FILESTAT_SET_SIZE) | wasi::__WASI_RIGHT_FD_FILESTAT_SET_SIZE)
!= 0; != 0;
let fd = hostcalls_impl::path_open(resolved, read, write, oflags, fs_flags)?; let fd = hostcalls_impl::path_open(resolved, read, write, oflags, fs_flags)?;
@@ -616,11 +577,11 @@ pub(crate) unsafe fn path_open(
pub(crate) unsafe fn fd_readdir( pub(crate) unsafe fn fd_readdir(
wasi_ctx: &mut WasiCtx, wasi_ctx: &mut WasiCtx,
memory: &mut [u8], memory: &mut [u8],
fd: wasm32::__wasi_fd_t, fd: wasi::__wasi_fd_t,
buf: wasm32::uintptr_t, buf: wasi32::uintptr_t,
buf_len: wasm32::size_t, buf_len: wasi32::size_t,
cookie: wasm32::__wasi_dircookie_t, cookie: wasi::__wasi_dircookie_t,
buf_used: wasm32::uintptr_t, buf_used: wasi32::uintptr_t,
) -> Result<()> { ) -> Result<()> {
trace!( trace!(
"fd_readdir(fd={:?}, buf={:#x?}, buf_len={}, cookie={:#x?}, buf_used={:#x?})", "fd_readdir(fd={:?}, buf={:#x?}, buf_len={}, cookie={:#x?}, buf_used={:#x?})",
@@ -633,17 +594,14 @@ pub(crate) unsafe fn fd_readdir(
enc_usize_byref(memory, buf_used, 0)?; enc_usize_byref(memory, buf_used, 0)?;
let fd = dec_fd(fd);
let file = wasi_ctx let file = wasi_ctx
.get_fd_entry_mut(fd)? .get_fd_entry_mut(fd)?
.as_descriptor_mut(host::__WASI_RIGHT_FD_READDIR, 0)? .as_descriptor_mut(wasi::__WASI_RIGHT_FD_READDIR, 0)?
.as_file_mut()?; .as_file_mut()?;
let host_buf = dec_slice_of_mut::<u8>(memory, buf, buf_len)?; let host_buf = dec_slice_of_mut_u8(memory, buf, buf_len)?;
trace!(" | (buf,buf_len)={:?}", host_buf); trace!(" | (buf,buf_len)={:?}", host_buf);
let cookie = dec_dircookie(cookie);
let host_bufused = hostcalls_impl::fd_readdir(file, host_buf, cookie)?; let host_bufused = hostcalls_impl::fd_readdir(file, host_buf, cookie)?;
trace!(" | *buf_used={:?}", host_bufused); trace!(" | *buf_used={:?}", host_bufused);
@@ -654,12 +612,12 @@ pub(crate) unsafe fn fd_readdir(
pub(crate) unsafe fn path_readlink( pub(crate) unsafe fn path_readlink(
wasi_ctx: &WasiCtx, wasi_ctx: &WasiCtx,
memory: &mut [u8], memory: &mut [u8],
dirfd: wasm32::__wasi_fd_t, dirfd: wasi::__wasi_fd_t,
path_ptr: wasm32::uintptr_t, path_ptr: wasi32::uintptr_t,
path_len: wasm32::size_t, path_len: wasi32::size_t,
buf_ptr: wasm32::uintptr_t, buf_ptr: wasi32::uintptr_t,
buf_len: wasm32::size_t, buf_len: wasi32::size_t,
buf_used: wasm32::uintptr_t, buf_used: wasi32::uintptr_t,
) -> Result<()> { ) -> Result<()> {
trace!( trace!(
"path_readlink(dirfd={:?}, path_ptr={:#x?}, path_len={:?}, buf_ptr={:#x?}, buf_len={}, buf_used={:#x?})", "path_readlink(dirfd={:?}, path_ptr={:#x?}, path_len={:?}, buf_ptr={:#x?}, buf_len={}, buf_used={:#x?})",
@@ -673,15 +631,14 @@ pub(crate) unsafe fn path_readlink(
enc_usize_byref(memory, buf_used, 0)?; enc_usize_byref(memory, buf_used, 0)?;
let dirfd = dec_fd(dirfd); let path = dec_slice_of_u8(memory, path_ptr, path_len).and_then(helpers::path_from_slice)?;
let path = dec_slice_of::<u8>(memory, path_ptr, path_len).and_then(host::path_from_slice)?;
trace!(" | (path_ptr,path_len)='{}'", &path); trace!(" | (path_ptr,path_len)='{}'", &path);
let fe = &wasi_ctx.get_fd_entry(dirfd)?; let fe = &wasi_ctx.get_fd_entry(dirfd)?;
let resolved = path_get(fe, host::__WASI_RIGHT_PATH_READLINK, 0, 0, &path, false)?; let resolved = path_get(fe, wasi::__WASI_RIGHT_PATH_READLINK, 0, 0, &path, false)?;
let mut buf = dec_slice_of_mut::<u8>(memory, buf_ptr, buf_len)?; let mut buf = dec_slice_of_mut_u8(memory, buf_ptr, buf_len)?;
let host_bufused = hostcalls_impl::path_readlink(resolved, &mut buf)?; let host_bufused = hostcalls_impl::path_readlink(resolved, &mut buf)?;
@@ -694,12 +651,12 @@ pub(crate) unsafe fn path_readlink(
pub(crate) unsafe fn path_rename( pub(crate) unsafe fn path_rename(
wasi_ctx: &WasiCtx, wasi_ctx: &WasiCtx,
memory: &mut [u8], memory: &mut [u8],
old_dirfd: wasm32::__wasi_fd_t, old_dirfd: wasi::__wasi_fd_t,
old_path_ptr: wasm32::uintptr_t, old_path_ptr: wasi32::uintptr_t,
old_path_len: wasm32::size_t, old_path_len: wasi32::size_t,
new_dirfd: wasm32::__wasi_fd_t, new_dirfd: wasi::__wasi_fd_t,
new_path_ptr: wasm32::uintptr_t, new_path_ptr: wasi32::uintptr_t,
new_path_len: wasm32::size_t, new_path_len: wasi32::size_t,
) -> Result<()> { ) -> Result<()> {
trace!( trace!(
"path_rename(old_dirfd={:?}, old_path_ptr={:#x?}, old_path_len={:?}, new_dirfd={:?}, new_path_ptr={:#x?}, new_path_len={:?})", "path_rename(old_dirfd={:?}, old_path_ptr={:#x?}, old_path_len={:?}, new_dirfd={:?}, new_path_ptr={:#x?}, new_path_len={:?})",
@@ -711,12 +668,8 @@ pub(crate) unsafe fn path_rename(
new_path_len, new_path_len,
); );
let old_dirfd = dec_fd(old_dirfd); let old_path = dec_slice_of_u8(memory, old_path_ptr, old_path_len).and_then(path_from_slice)?;
let new_dirfd = dec_fd(new_dirfd); let new_path = dec_slice_of_u8(memory, new_path_ptr, new_path_len).and_then(path_from_slice)?;
let old_path =
dec_slice_of::<u8>(memory, old_path_ptr, old_path_len).and_then(host::path_from_slice)?;
let new_path =
dec_slice_of::<u8>(memory, new_path_ptr, new_path_len).and_then(host::path_from_slice)?;
trace!(" | (old_path_ptr,old_path_len)='{}'", old_path); trace!(" | (old_path_ptr,old_path_len)='{}'", old_path);
trace!(" | (new_path_ptr,new_path_len)='{}'", new_path); trace!(" | (new_path_ptr,new_path_len)='{}'", new_path);
@@ -725,7 +678,7 @@ pub(crate) unsafe fn path_rename(
let new_fe = &wasi_ctx.get_fd_entry(new_dirfd)?; let new_fe = &wasi_ctx.get_fd_entry(new_dirfd)?;
let resolved_old = path_get( let resolved_old = path_get(
old_fe, old_fe,
host::__WASI_RIGHT_PATH_RENAME_SOURCE, wasi::__WASI_RIGHT_PATH_RENAME_SOURCE,
0, 0,
0, 0,
old_path, old_path,
@@ -733,7 +686,7 @@ pub(crate) unsafe fn path_rename(
)?; )?;
let resolved_new = path_get( let resolved_new = path_get(
new_fe, new_fe,
host::__WASI_RIGHT_PATH_RENAME_TARGET, wasi::__WASI_RIGHT_PATH_RENAME_TARGET,
0, 0,
0, 0,
new_path, new_path,
@@ -749,8 +702,8 @@ pub(crate) unsafe fn path_rename(
pub(crate) unsafe fn fd_filestat_get( pub(crate) unsafe fn fd_filestat_get(
wasi_ctx: &WasiCtx, wasi_ctx: &WasiCtx,
memory: &mut [u8], memory: &mut [u8],
fd: wasm32::__wasi_fd_t, fd: wasi::__wasi_fd_t,
filestat_ptr: wasm32::uintptr_t, filestat_ptr: wasi32::uintptr_t,
) -> Result<()> { ) -> Result<()> {
trace!( trace!(
"fd_filestat_get(fd={:?}, filestat_ptr={:#x?})", "fd_filestat_get(fd={:?}, filestat_ptr={:#x?})",
@@ -758,7 +711,6 @@ pub(crate) unsafe fn fd_filestat_get(
filestat_ptr filestat_ptr
); );
let fd = dec_fd(fd);
let fd = wasi_ctx.get_fd_entry(fd)?.as_descriptor(0, 0)?.as_file()?; let fd = wasi_ctx.get_fd_entry(fd)?.as_descriptor(0, 0)?.as_file()?;
let host_filestat = hostcalls_impl::fd_filestat_get_impl(fd)?; let host_filestat = hostcalls_impl::fd_filestat_get_impl(fd)?;
@@ -770,10 +722,10 @@ pub(crate) unsafe fn fd_filestat_get(
pub(crate) unsafe fn fd_filestat_set_times( pub(crate) unsafe fn fd_filestat_set_times(
wasi_ctx: &WasiCtx, wasi_ctx: &WasiCtx,
fd: wasm32::__wasi_fd_t, fd: wasi::__wasi_fd_t,
st_atim: wasm32::__wasi_timestamp_t, st_atim: wasi::__wasi_timestamp_t,
st_mtim: wasm32::__wasi_timestamp_t, st_mtim: wasi::__wasi_timestamp_t,
fst_flags: wasm32::__wasi_fstflags_t, fst_flags: wasi::__wasi_fstflags_t,
) -> Result<()> { ) -> Result<()> {
trace!( trace!(
"fd_filestat_set_times(fd={:?}, st_atim={}, st_mtim={}, fst_flags={:#x?})", "fd_filestat_set_times(fd={:?}, st_atim={}, st_mtim={}, fst_flags={:#x?})",
@@ -783,29 +735,24 @@ pub(crate) unsafe fn fd_filestat_set_times(
fst_flags fst_flags
); );
let fd = dec_fd(fd);
let fd = wasi_ctx let fd = wasi_ctx
.get_fd_entry(fd)? .get_fd_entry(fd)?
.as_descriptor(host::__WASI_RIGHT_FD_FILESTAT_SET_TIMES, 0)? .as_descriptor(wasi::__WASI_RIGHT_FD_FILESTAT_SET_TIMES, 0)?
.as_file()?; .as_file()?;
let st_atim = dec_timestamp(st_atim);
let st_mtim = dec_timestamp(st_mtim);
let fst_flags = dec_fstflags(fst_flags);
fd_filestat_set_times_impl(fd, st_atim, st_mtim, fst_flags) fd_filestat_set_times_impl(fd, st_atim, st_mtim, fst_flags)
} }
pub(crate) fn fd_filestat_set_times_impl( pub(crate) fn fd_filestat_set_times_impl(
fd: &File, fd: &File,
st_atim: wasm32::__wasi_timestamp_t, st_atim: wasi::__wasi_timestamp_t,
st_mtim: wasm32::__wasi_timestamp_t, st_mtim: wasi::__wasi_timestamp_t,
fst_flags: wasm32::__wasi_fstflags_t, fst_flags: wasi::__wasi_fstflags_t,
) -> Result<()> { ) -> Result<()> {
let set_atim = fst_flags & host::__WASI_FILESTAT_SET_ATIM != 0; let set_atim = fst_flags & wasi::__WASI_FILESTAT_SET_ATIM != 0;
let set_atim_now = fst_flags & host::__WASI_FILESTAT_SET_ATIM_NOW != 0; let set_atim_now = fst_flags & wasi::__WASI_FILESTAT_SET_ATIM_NOW != 0;
let set_mtim = fst_flags & host::__WASI_FILESTAT_SET_MTIM != 0; let set_mtim = fst_flags & wasi::__WASI_FILESTAT_SET_MTIM != 0;
let set_mtim_now = fst_flags & host::__WASI_FILESTAT_SET_MTIM_NOW != 0; let set_mtim_now = fst_flags & wasi::__WASI_FILESTAT_SET_MTIM_NOW != 0;
if (set_atim && set_atim_now) || (set_mtim && set_mtim_now) { if (set_atim && set_atim_now) || (set_mtim && set_mtim_now) {
return Err(Error::EINVAL); return Err(Error::EINVAL);
@@ -834,18 +781,16 @@ pub(crate) fn fd_filestat_set_times_impl(
pub(crate) unsafe fn fd_filestat_set_size( pub(crate) unsafe fn fd_filestat_set_size(
wasi_ctx: &WasiCtx, wasi_ctx: &WasiCtx,
fd: wasm32::__wasi_fd_t, fd: wasi::__wasi_fd_t,
st_size: wasm32::__wasi_filesize_t, st_size: wasi::__wasi_filesize_t,
) -> Result<()> { ) -> Result<()> {
trace!("fd_filestat_set_size(fd={:?}, st_size={})", fd, st_size); trace!("fd_filestat_set_size(fd={:?}, st_size={})", fd, st_size);
let fd = dec_fd(fd);
let fd = wasi_ctx let fd = wasi_ctx
.get_fd_entry(fd)? .get_fd_entry(fd)?
.as_descriptor(host::__WASI_RIGHT_FD_FILESTAT_SET_SIZE, 0)? .as_descriptor(wasi::__WASI_RIGHT_FD_FILESTAT_SET_SIZE, 0)?
.as_file()?; .as_file()?;
let st_size = dec_filesize(st_size);
// This check will be unnecessary when rust-lang/rust#63326 is fixed // This check will be unnecessary when rust-lang/rust#63326 is fixed
if st_size > i64::max_value() as u64 { if st_size > i64::max_value() as u64 {
return Err(Error::E2BIG); return Err(Error::E2BIG);
@@ -856,11 +801,11 @@ pub(crate) unsafe fn fd_filestat_set_size(
pub(crate) unsafe fn path_filestat_get( pub(crate) unsafe fn path_filestat_get(
wasi_ctx: &WasiCtx, wasi_ctx: &WasiCtx,
memory: &mut [u8], memory: &mut [u8],
dirfd: wasm32::__wasi_fd_t, dirfd: wasi::__wasi_fd_t,
dirflags: wasm32::__wasi_lookupflags_t, dirflags: wasi::__wasi_lookupflags_t,
path_ptr: wasm32::uintptr_t, path_ptr: wasi32::uintptr_t,
path_len: wasm32::size_t, path_len: wasi32::size_t,
filestat_ptr: wasm32::uintptr_t, filestat_ptr: wasi32::uintptr_t,
) -> Result<()> { ) -> Result<()> {
trace!( trace!(
"path_filestat_get(dirfd={:?}, dirflags={:?}, path_ptr={:#x?}, path_len={}, filestat_ptr={:#x?})", "path_filestat_get(dirfd={:?}, dirflags={:?}, path_ptr={:#x?}, path_len={}, filestat_ptr={:#x?})",
@@ -871,16 +816,14 @@ pub(crate) unsafe fn path_filestat_get(
filestat_ptr filestat_ptr
); );
let dirfd = dec_fd(dirfd); let path = dec_slice_of_u8(memory, path_ptr, path_len).and_then(path_from_slice)?;
let dirflags = dec_lookupflags(dirflags);
let path = dec_slice_of::<u8>(memory, path_ptr, path_len).and_then(host::path_from_slice)?;
trace!(" | (path_ptr,path_len)='{}'", path); trace!(" | (path_ptr,path_len)='{}'", path);
let fe = &wasi_ctx.get_fd_entry(dirfd)?; let fe = &wasi_ctx.get_fd_entry(dirfd)?;
let resolved = path_get( let resolved = path_get(
fe, fe,
host::__WASI_RIGHT_PATH_FILESTAT_GET, wasi::__WASI_RIGHT_PATH_FILESTAT_GET,
0, 0,
dirflags, dirflags,
path, path,
@@ -896,13 +839,13 @@ pub(crate) unsafe fn path_filestat_get(
pub(crate) unsafe fn path_filestat_set_times( pub(crate) unsafe fn path_filestat_set_times(
wasi_ctx: &WasiCtx, wasi_ctx: &WasiCtx,
memory: &mut [u8], memory: &mut [u8],
dirfd: wasm32::__wasi_fd_t, dirfd: wasi::__wasi_fd_t,
dirflags: wasm32::__wasi_lookupflags_t, dirflags: wasi::__wasi_lookupflags_t,
path_ptr: wasm32::uintptr_t, path_ptr: wasi32::uintptr_t,
path_len: wasm32::size_t, path_len: wasi32::size_t,
st_atim: wasm32::__wasi_timestamp_t, st_atim: wasi::__wasi_timestamp_t,
st_mtim: wasm32::__wasi_timestamp_t, st_mtim: wasi::__wasi_timestamp_t,
fst_flags: wasm32::__wasi_fstflags_t, fst_flags: wasi::__wasi_fstflags_t,
) -> Result<()> { ) -> Result<()> {
trace!( trace!(
"path_filestat_set_times(dirfd={:?}, dirflags={:?}, path_ptr={:#x?}, path_len={}, st_atim={}, st_mtim={}, fst_flags={:#x?})", "path_filestat_set_times(dirfd={:?}, dirflags={:?}, path_ptr={:#x?}, path_len={}, st_atim={}, st_mtim={}, fst_flags={:#x?})",
@@ -914,20 +857,14 @@ pub(crate) unsafe fn path_filestat_set_times(
fst_flags fst_flags
); );
let dirfd = dec_fd(dirfd); let path = dec_slice_of_u8(memory, path_ptr, path_len).and_then(path_from_slice)?;
let dirflags = dec_lookupflags(dirflags);
let path = dec_slice_of::<u8>(memory, path_ptr, path_len).and_then(host::path_from_slice)?;
trace!(" | (path_ptr,path_len)='{}'", path); trace!(" | (path_ptr,path_len)='{}'", path);
let st_atim = dec_timestamp(st_atim);
let st_mtim = dec_timestamp(st_mtim);
let fst_flags = dec_fstflags(fst_flags);
let fe = &wasi_ctx.get_fd_entry(dirfd)?; let fe = &wasi_ctx.get_fd_entry(dirfd)?;
let resolved = path_get( let resolved = path_get(
fe, fe,
host::__WASI_RIGHT_PATH_FILESTAT_SET_TIMES, wasi::__WASI_RIGHT_PATH_FILESTAT_SET_TIMES,
0, 0,
dirflags, dirflags,
path, path,
@@ -940,11 +877,11 @@ pub(crate) unsafe fn path_filestat_set_times(
pub(crate) unsafe fn path_symlink( pub(crate) unsafe fn path_symlink(
wasi_ctx: &WasiCtx, wasi_ctx: &WasiCtx,
memory: &mut [u8], memory: &mut [u8],
old_path_ptr: wasm32::uintptr_t, old_path_ptr: wasi32::uintptr_t,
old_path_len: wasm32::size_t, old_path_len: wasi32::size_t,
dirfd: wasm32::__wasi_fd_t, dirfd: wasi::__wasi_fd_t,
new_path_ptr: wasm32::uintptr_t, new_path_ptr: wasi32::uintptr_t,
new_path_len: wasm32::size_t, new_path_len: wasi32::size_t,
) -> Result<()> { ) -> Result<()> {
trace!( trace!(
"path_symlink(old_path_ptr={:#x?}, old_path_len={}, dirfd={:?}, new_path_ptr={:#x?}, new_path_len={})", "path_symlink(old_path_ptr={:#x?}, old_path_len={}, dirfd={:?}, new_path_ptr={:#x?}, new_path_len={})",
@@ -955,17 +892,14 @@ pub(crate) unsafe fn path_symlink(
new_path_len new_path_len
); );
let dirfd = dec_fd(dirfd); let old_path = dec_slice_of_u8(memory, old_path_ptr, old_path_len).and_then(path_from_slice)?;
let old_path = let new_path = dec_slice_of_u8(memory, new_path_ptr, new_path_len).and_then(path_from_slice)?;
dec_slice_of::<u8>(memory, old_path_ptr, old_path_len).and_then(host::path_from_slice)?;
let new_path =
dec_slice_of::<u8>(memory, new_path_ptr, new_path_len).and_then(host::path_from_slice)?;
trace!(" | (old_path_ptr,old_path_len)='{}'", old_path); trace!(" | (old_path_ptr,old_path_len)='{}'", old_path);
trace!(" | (new_path_ptr,new_path_len)='{}'", new_path); trace!(" | (new_path_ptr,new_path_len)='{}'", new_path);
let fe = &wasi_ctx.get_fd_entry(dirfd)?; let fe = &wasi_ctx.get_fd_entry(dirfd)?;
let resolved_new = path_get(fe, host::__WASI_RIGHT_PATH_SYMLINK, 0, 0, new_path, true)?; let resolved_new = path_get(fe, wasi::__WASI_RIGHT_PATH_SYMLINK, 0, 0, new_path, true)?;
hostcalls_impl::path_symlink(old_path, resolved_new) hostcalls_impl::path_symlink(old_path, resolved_new)
} }
@@ -973,9 +907,9 @@ pub(crate) unsafe fn path_symlink(
pub(crate) unsafe fn path_unlink_file( pub(crate) unsafe fn path_unlink_file(
wasi_ctx: &WasiCtx, wasi_ctx: &WasiCtx,
memory: &mut [u8], memory: &mut [u8],
dirfd: wasm32::__wasi_fd_t, dirfd: wasi::__wasi_fd_t,
path_ptr: wasm32::uintptr_t, path_ptr: wasi32::uintptr_t,
path_len: wasm32::size_t, path_len: wasi32::size_t,
) -> Result<()> { ) -> Result<()> {
trace!( trace!(
"path_unlink_file(dirfd={:?}, path_ptr={:#x?}, path_len={})", "path_unlink_file(dirfd={:?}, path_ptr={:#x?}, path_len={})",
@@ -984,13 +918,12 @@ pub(crate) unsafe fn path_unlink_file(
path_len path_len
); );
let dirfd = dec_fd(dirfd); let path = dec_slice_of_u8(memory, path_ptr, path_len).and_then(path_from_slice)?;
let path = dec_slice_of::<u8>(memory, path_ptr, path_len).and_then(host::path_from_slice)?;
trace!(" | (path_ptr,path_len)='{}'", path); trace!(" | (path_ptr,path_len)='{}'", path);
let fe = &wasi_ctx.get_fd_entry(dirfd)?; let fe = &wasi_ctx.get_fd_entry(dirfd)?;
let resolved = path_get(fe, host::__WASI_RIGHT_PATH_UNLINK_FILE, 0, 0, path, false)?; let resolved = path_get(fe, wasi::__WASI_RIGHT_PATH_UNLINK_FILE, 0, 0, path, false)?;
hostcalls_impl::path_unlink_file(resolved) hostcalls_impl::path_unlink_file(resolved)
} }
@@ -998,9 +931,9 @@ pub(crate) unsafe fn path_unlink_file(
pub(crate) unsafe fn path_remove_directory( pub(crate) unsafe fn path_remove_directory(
wasi_ctx: &WasiCtx, wasi_ctx: &WasiCtx,
memory: &mut [u8], memory: &mut [u8],
dirfd: wasm32::__wasi_fd_t, dirfd: wasi::__wasi_fd_t,
path_ptr: wasm32::uintptr_t, path_ptr: wasi32::uintptr_t,
path_len: wasm32::size_t, path_len: wasi32::size_t,
) -> Result<()> { ) -> Result<()> {
trace!( trace!(
"path_remove_directory(dirfd={:?}, path_ptr={:#x?}, path_len={})", "path_remove_directory(dirfd={:?}, path_ptr={:#x?}, path_len={})",
@@ -1009,15 +942,14 @@ pub(crate) unsafe fn path_remove_directory(
path_len path_len
); );
let dirfd = dec_fd(dirfd); let path = dec_slice_of_u8(memory, path_ptr, path_len).and_then(path_from_slice)?;
let path = dec_slice_of::<u8>(memory, path_ptr, path_len).and_then(host::path_from_slice)?;
trace!(" | (path_ptr,path_len)='{}'", path); trace!(" | (path_ptr,path_len)='{}'", path);
let fe = &wasi_ctx.get_fd_entry(dirfd)?; let fe = &wasi_ctx.get_fd_entry(dirfd)?;
let resolved = path_get( let resolved = path_get(
fe, fe,
host::__WASI_RIGHT_PATH_REMOVE_DIRECTORY, wasi::__WASI_RIGHT_PATH_REMOVE_DIRECTORY,
0, 0,
0, 0,
path, path,
@@ -1032,8 +964,8 @@ pub(crate) unsafe fn path_remove_directory(
pub(crate) unsafe fn fd_prestat_get( pub(crate) unsafe fn fd_prestat_get(
wasi_ctx: &WasiCtx, wasi_ctx: &WasiCtx,
memory: &mut [u8], memory: &mut [u8],
fd: wasm32::__wasi_fd_t, fd: wasi::__wasi_fd_t,
prestat_ptr: wasm32::uintptr_t, prestat_ptr: wasi32::uintptr_t,
) -> Result<()> { ) -> Result<()> {
trace!( trace!(
"fd_prestat_get(fd={:?}, prestat_ptr={:#x?})", "fd_prestat_get(fd={:?}, prestat_ptr={:#x?})",
@@ -1041,11 +973,10 @@ pub(crate) unsafe fn fd_prestat_get(
prestat_ptr prestat_ptr
); );
let fd = dec_fd(fd);
// TODO: should we validate any rights here? // TODO: should we validate any rights here?
let fe = &wasi_ctx.get_fd_entry(fd)?; let fe = &wasi_ctx.get_fd_entry(fd)?;
let po_path = fe.preopen_path.as_ref().ok_or(Error::ENOTSUP)?; let po_path = fe.preopen_path.as_ref().ok_or(Error::ENOTSUP)?;
if fe.file_type != host::__WASI_FILETYPE_DIRECTORY { if fe.file_type != wasi::__WASI_FILETYPE_DIRECTORY {
return Err(Error::ENOTDIR); return Err(Error::ENOTDIR);
} }
@@ -1055,7 +986,7 @@ pub(crate) unsafe fn fd_prestat_get(
memory, memory,
prestat_ptr, prestat_ptr,
host::__wasi_prestat_t { host::__wasi_prestat_t {
pr_type: host::__WASI_PREOPENTYPE_DIR, pr_type: wasi::__WASI_PREOPENTYPE_DIR,
u: host::__wasi_prestat_t___wasi_prestat_u { u: host::__wasi_prestat_t___wasi_prestat_u {
dir: host::__wasi_prestat_t___wasi_prestat_u___wasi_prestat_u_dir_t { dir: host::__wasi_prestat_t___wasi_prestat_u___wasi_prestat_u_dir_t {
pr_name_len: path.len(), pr_name_len: path.len(),
@@ -1068,9 +999,9 @@ pub(crate) unsafe fn fd_prestat_get(
pub(crate) unsafe fn fd_prestat_dir_name( pub(crate) unsafe fn fd_prestat_dir_name(
wasi_ctx: &WasiCtx, wasi_ctx: &WasiCtx,
memory: &mut [u8], memory: &mut [u8],
fd: wasm32::__wasi_fd_t, fd: wasi::__wasi_fd_t,
path_ptr: wasm32::uintptr_t, path_ptr: wasi32::uintptr_t,
path_len: wasm32::size_t, path_len: wasi32::size_t,
) -> Result<()> { ) -> Result<()> {
trace!( trace!(
"fd_prestat_dir_name(fd={:?}, path_ptr={:#x?}, path_len={})", "fd_prestat_dir_name(fd={:?}, path_ptr={:#x?}, path_len={})",
@@ -1079,11 +1010,10 @@ pub(crate) unsafe fn fd_prestat_dir_name(
path_len path_len
); );
let fd = dec_fd(fd);
// TODO: should we validate any rights here? // TODO: should we validate any rights here?
let fe = &wasi_ctx.get_fd_entry(fd)?; let fe = &wasi_ctx.get_fd_entry(fd)?;
let po_path = fe.preopen_path.as_ref().ok_or(Error::ENOTSUP)?; let po_path = fe.preopen_path.as_ref().ok_or(Error::ENOTSUP)?;
if fe.file_type != host::__WASI_FILETYPE_DIRECTORY { if fe.file_type != wasi::__WASI_FILETYPE_DIRECTORY {
return Err(Error::ENOTDIR); return Err(Error::ENOTDIR);
} }
@@ -1095,25 +1025,25 @@ pub(crate) unsafe fn fd_prestat_dir_name(
trace!(" | (path_ptr,path_len)='{}'", path); trace!(" | (path_ptr,path_len)='{}'", path);
enc_slice_of(memory, path.as_bytes(), path_ptr) enc_slice_of_u8(memory, path.as_bytes(), path_ptr)
} }
#[allow(dead_code)] // trouble with sockets #[allow(dead_code)] // trouble with sockets
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
#[repr(u8)] #[repr(u8)]
pub(crate) enum FileType { pub(crate) enum FileType {
Unknown = host::__WASI_FILETYPE_UNKNOWN, Unknown = wasi::__WASI_FILETYPE_UNKNOWN,
BlockDevice = host::__WASI_FILETYPE_BLOCK_DEVICE, BlockDevice = wasi::__WASI_FILETYPE_BLOCK_DEVICE,
CharacterDevice = host::__WASI_FILETYPE_CHARACTER_DEVICE, CharacterDevice = wasi::__WASI_FILETYPE_CHARACTER_DEVICE,
Directory = host::__WASI_FILETYPE_DIRECTORY, Directory = wasi::__WASI_FILETYPE_DIRECTORY,
RegularFile = host::__WASI_FILETYPE_REGULAR_FILE, RegularFile = wasi::__WASI_FILETYPE_REGULAR_FILE,
SocketDgram = host::__WASI_FILETYPE_SOCKET_DGRAM, SocketDgram = wasi::__WASI_FILETYPE_SOCKET_DGRAM,
SocketStream = host::__WASI_FILETYPE_SOCKET_STREAM, SocketStream = wasi::__WASI_FILETYPE_SOCKET_STREAM,
Symlink = host::__WASI_FILETYPE_SYMBOLIC_LINK, Symlink = wasi::__WASI_FILETYPE_SYMBOLIC_LINK,
} }
impl FileType { impl FileType {
pub(crate) fn to_wasi(&self) -> host::__wasi_filetype_t { pub(crate) fn to_wasi(&self) -> wasi::__wasi_filetype_t {
*self as host::__wasi_filetype_t *self as wasi::__wasi_filetype_t
} }
} }

View File

@@ -1,7 +1,7 @@
#![allow(non_camel_case_types)] #![allow(non_camel_case_types)]
use crate::sys::host_impl; use crate::sys::host_impl;
use crate::sys::hostcalls_impl::fs_helpers::*; use crate::sys::hostcalls_impl::fs_helpers::*;
use crate::{fdentry::FdEntry, host, Error, Result}; use crate::{fdentry::FdEntry, wasi, Error, Result};
use std::fs::File; use std::fs::File;
use std::path::{Component, Path}; use std::path::{Component, Path};
@@ -26,9 +26,9 @@ impl PathGet {
/// This is a workaround for not having Capsicum support in the OS. /// This is a workaround for not having Capsicum support in the OS.
pub(crate) fn path_get( pub(crate) fn path_get(
fe: &FdEntry, fe: &FdEntry,
rights_base: host::__wasi_rights_t, rights_base: wasi::__wasi_rights_t,
rights_inheriting: host::__wasi_rights_t, rights_inheriting: wasi::__wasi_rights_t,
dirflags: host::__wasi_lookupflags_t, dirflags: wasi::__wasi_lookupflags_t,
path: &str, path: &str,
needs_final_component: bool, needs_final_component: bool,
) -> Result<PathGet> { ) -> Result<PathGet> {
@@ -39,7 +39,7 @@ pub(crate) fn path_get(
return Err(Error::EILSEQ); return Err(Error::EILSEQ);
} }
if fe.file_type != host::__WASI_FILETYPE_DIRECTORY { if fe.file_type != wasi::__WASI_FILETYPE_DIRECTORY {
// if `dirfd` doesn't refer to a directory, return `ENOTDIR`. // if `dirfd` doesn't refer to a directory, return `ENOTDIR`.
return Err(Error::ENOTDIR); return Err(Error::ENOTDIR);
} }
@@ -118,9 +118,9 @@ pub(crate) fn path_get(
} }
Err(e) => { Err(e) => {
match e.as_wasi_errno() { match e.as_wasi_errno() {
host::__WASI_ELOOP wasi::__WASI_ELOOP
| host::__WASI_EMLINK | wasi::__WASI_EMLINK
| host::__WASI_ENOTDIR => | wasi::__WASI_ENOTDIR =>
// Check to see if it was a symlink. Linux indicates // Check to see if it was a symlink. Linux indicates
// this with ENOTDIR because of the O_DIRECTORY flag. // this with ENOTDIR because of the O_DIRECTORY flag.
{ {
@@ -155,7 +155,7 @@ pub(crate) fn path_get(
continue; continue;
} else if ends_with_slash } else if ends_with_slash
|| (dirflags & host::__WASI_LOOKUP_SYMLINK_FOLLOW) != 0 || (dirflags & wasi::__WASI_LOOKUP_SYMLINK_FOLLOW) != 0
{ {
// if there's a trailing slash, or if `LOOKUP_SYMLINK_FOLLOW` is set, attempt // if there's a trailing slash, or if `LOOKUP_SYMLINK_FOLLOW` is set, attempt
// symlink expansion // symlink expansion
@@ -179,12 +179,12 @@ pub(crate) fn path_get(
continue; continue;
} }
Err(e) => { Err(e) => {
if e.as_wasi_errno() != host::__WASI_EINVAL if e.as_wasi_errno() != wasi::__WASI_EINVAL
&& e.as_wasi_errno() != host::__WASI_ENOENT && e.as_wasi_errno() != wasi::__WASI_ENOENT
// this handles the cases when trying to link to // this handles the cases when trying to link to
// a destination that already exists, and the target // a destination that already exists, and the target
// path contains a slash // path contains a slash
&& e.as_wasi_errno() != host::__WASI_ENOTDIR && e.as_wasi_errno() != wasi::__WASI_ENOTDIR
{ {
return Err(e); return Err(e);
} }

View File

@@ -3,15 +3,15 @@ use crate::ctx::WasiCtx;
use crate::fdentry::Descriptor; use crate::fdentry::Descriptor;
use crate::memory::*; use crate::memory::*;
use crate::sys::hostcalls_impl; use crate::sys::hostcalls_impl;
use crate::{host, wasm32, Error, Result}; use crate::{wasi, wasi32, Error, Result};
use log::trace; use log::trace;
use std::convert::TryFrom; use std::convert::TryFrom;
pub(crate) fn args_get( pub(crate) fn args_get(
wasi_ctx: &WasiCtx, wasi_ctx: &WasiCtx,
memory: &mut [u8], memory: &mut [u8],
argv_ptr: wasm32::uintptr_t, argv_ptr: wasi32::uintptr_t,
argv_buf: wasm32::uintptr_t, argv_buf: wasi32::uintptr_t,
) -> Result<()> { ) -> Result<()> {
trace!( trace!(
"args_get(argv_ptr={:#x?}, argv_buf={:#x?})", "args_get(argv_ptr={:#x?}, argv_buf={:#x?})",
@@ -26,22 +26,22 @@ pub(crate) fn args_get(
let arg_bytes = arg.as_bytes_with_nul(); let arg_bytes = arg.as_bytes_with_nul();
let arg_ptr = argv_buf + argv_buf_offset; let arg_ptr = argv_buf + argv_buf_offset;
enc_slice_of(memory, arg_bytes, arg_ptr)?; enc_slice_of_u8(memory, arg_bytes, arg_ptr)?;
argv.push(arg_ptr); argv.push(arg_ptr);
let len = wasm32::uintptr_t::try_from(arg_bytes.len())?; let len = wasi32::uintptr_t::try_from(arg_bytes.len())?;
argv_buf_offset = argv_buf_offset.checked_add(len).ok_or(Error::EOVERFLOW)?; argv_buf_offset = argv_buf_offset.checked_add(len).ok_or(Error::EOVERFLOW)?;
} }
enc_slice_of(memory, argv.as_slice(), argv_ptr) enc_slice_of_wasi32_uintptr(memory, argv.as_slice(), argv_ptr)
} }
pub(crate) fn args_sizes_get( pub(crate) fn args_sizes_get(
wasi_ctx: &WasiCtx, wasi_ctx: &WasiCtx,
memory: &mut [u8], memory: &mut [u8],
argc_ptr: wasm32::uintptr_t, argc_ptr: wasi32::uintptr_t,
argv_buf_size_ptr: wasm32::uintptr_t, argv_buf_size_ptr: wasi32::uintptr_t,
) -> Result<()> { ) -> Result<()> {
trace!( trace!(
"args_sizes_get(argc_ptr={:#x?}, argv_buf_size_ptr={:#x?})", "args_sizes_get(argc_ptr={:#x?}, argv_buf_size_ptr={:#x?})",
@@ -68,8 +68,8 @@ pub(crate) fn args_sizes_get(
pub(crate) fn environ_get( pub(crate) fn environ_get(
wasi_ctx: &WasiCtx, wasi_ctx: &WasiCtx,
memory: &mut [u8], memory: &mut [u8],
environ_ptr: wasm32::uintptr_t, environ_ptr: wasi32::uintptr_t,
environ_buf: wasm32::uintptr_t, environ_buf: wasi32::uintptr_t,
) -> Result<()> { ) -> Result<()> {
trace!( trace!(
"environ_get(environ_ptr={:#x?}, environ_buf={:#x?})", "environ_get(environ_ptr={:#x?}, environ_buf={:#x?})",
@@ -84,24 +84,24 @@ pub(crate) fn environ_get(
let env_bytes = pair.as_bytes_with_nul(); let env_bytes = pair.as_bytes_with_nul();
let env_ptr = environ_buf + environ_buf_offset; let env_ptr = environ_buf + environ_buf_offset;
enc_slice_of(memory, env_bytes, env_ptr)?; enc_slice_of_u8(memory, env_bytes, env_ptr)?;
environ.push(env_ptr); environ.push(env_ptr);
let len = wasm32::uintptr_t::try_from(env_bytes.len())?; let len = wasi32::uintptr_t::try_from(env_bytes.len())?;
environ_buf_offset = environ_buf_offset environ_buf_offset = environ_buf_offset
.checked_add(len) .checked_add(len)
.ok_or(Error::EOVERFLOW)?; .ok_or(Error::EOVERFLOW)?;
} }
enc_slice_of(memory, environ.as_slice(), environ_ptr) enc_slice_of_wasi32_uintptr(memory, environ.as_slice(), environ_ptr)
} }
pub(crate) fn environ_sizes_get( pub(crate) fn environ_sizes_get(
wasi_ctx: &WasiCtx, wasi_ctx: &WasiCtx,
memory: &mut [u8], memory: &mut [u8],
environ_count_ptr: wasm32::uintptr_t, environ_count_ptr: wasi32::uintptr_t,
environ_size_ptr: wasm32::uintptr_t, environ_size_ptr: wasi32::uintptr_t,
) -> Result<()> { ) -> Result<()> {
trace!( trace!(
"environ_sizes_get(environ_count_ptr={:#x?}, environ_size_ptr={:#x?})", "environ_sizes_get(environ_count_ptr={:#x?}, environ_size_ptr={:#x?})",
@@ -129,14 +129,14 @@ pub(crate) fn environ_sizes_get(
pub(crate) fn random_get( pub(crate) fn random_get(
memory: &mut [u8], memory: &mut [u8],
buf_ptr: wasm32::uintptr_t, buf_ptr: wasi32::uintptr_t,
buf_len: wasm32::size_t, buf_len: wasi32::size_t,
) -> Result<()> { ) -> Result<()> {
use rand::{thread_rng, RngCore}; use rand::{thread_rng, RngCore};
trace!("random_get(buf_ptr={:#x?}, buf_len={:?})", buf_ptr, buf_len); trace!("random_get(buf_ptr={:#x?}, buf_len={:?})", buf_ptr, buf_len);
let buf = dec_slice_of_mut::<u8>(memory, buf_ptr, buf_len)?; let buf = dec_slice_of_mut_u8(memory, buf_ptr, buf_len)?;
thread_rng().fill_bytes(buf); thread_rng().fill_bytes(buf);
@@ -145,8 +145,8 @@ pub(crate) fn random_get(
pub(crate) fn clock_res_get( pub(crate) fn clock_res_get(
memory: &mut [u8], memory: &mut [u8],
clock_id: wasm32::__wasi_clockid_t, clock_id: wasi::__wasi_clockid_t,
resolution_ptr: wasm32::uintptr_t, resolution_ptr: wasi32::uintptr_t,
) -> Result<()> { ) -> Result<()> {
trace!( trace!(
"clock_res_get(clock_id={:?}, resolution_ptr={:#x?})", "clock_res_get(clock_id={:?}, resolution_ptr={:#x?})",
@@ -154,7 +154,6 @@ pub(crate) fn clock_res_get(
resolution_ptr, resolution_ptr,
); );
let clock_id = dec_clockid(clock_id);
let resolution = hostcalls_impl::clock_res_get(clock_id)?; let resolution = hostcalls_impl::clock_res_get(clock_id)?;
trace!(" | *resolution_ptr={:?}", resolution); trace!(" | *resolution_ptr={:?}", resolution);
@@ -164,9 +163,9 @@ pub(crate) fn clock_res_get(
pub(crate) fn clock_time_get( pub(crate) fn clock_time_get(
memory: &mut [u8], memory: &mut [u8],
clock_id: wasm32::__wasi_clockid_t, clock_id: wasi::__wasi_clockid_t,
precision: wasm32::__wasi_timestamp_t, precision: wasi::__wasi_timestamp_t,
time_ptr: wasm32::uintptr_t, time_ptr: wasi32::uintptr_t,
) -> Result<()> { ) -> Result<()> {
trace!( trace!(
"clock_time_get(clock_id={:?}, precision={:?}, time_ptr={:#x?})", "clock_time_get(clock_id={:?}, precision={:?}, time_ptr={:#x?})",
@@ -175,7 +174,6 @@ pub(crate) fn clock_time_get(
time_ptr, time_ptr,
); );
let clock_id = dec_clockid(clock_id);
let time = hostcalls_impl::clock_time_get(clock_id)?; let time = hostcalls_impl::clock_time_get(clock_id)?;
trace!(" | *time_ptr={:?}", time); trace!(" | *time_ptr={:?}", time);
@@ -194,10 +192,10 @@ pub(crate) fn sched_yield() -> Result<()> {
pub(crate) fn poll_oneoff( pub(crate) fn poll_oneoff(
wasi_ctx: &WasiCtx, wasi_ctx: &WasiCtx,
memory: &mut [u8], memory: &mut [u8],
input: wasm32::uintptr_t, input: wasi32::uintptr_t,
output: wasm32::uintptr_t, output: wasi32::uintptr_t,
nsubscriptions: wasm32::size_t, nsubscriptions: wasi32::size_t,
nevents: wasm32::uintptr_t, nevents: wasi32::uintptr_t,
) -> Result<()> { ) -> Result<()> {
trace!( trace!(
"poll_oneoff(input={:#x?}, output={:#x?}, nsubscriptions={}, nevents={:#x?})", "poll_oneoff(input={:#x?}, output={:#x?}, nsubscriptions={}, nevents={:#x?})",
@@ -207,26 +205,20 @@ pub(crate) fn poll_oneoff(
nevents, nevents,
); );
if u64::from(nsubscriptions) > wasm32::__wasi_filesize_t::max_value() { if u64::from(nsubscriptions) > wasi::__wasi_filesize_t::max_value() {
return Err(Error::EINVAL); return Err(Error::EINVAL);
} }
enc_pointee(memory, nevents, 0)?; enc_int_byref(memory, nevents, 0)?;
let input_slice = dec_slice_of::<wasm32::__wasi_subscription_t>(memory, input, nsubscriptions)?; let subscriptions = dec_subscriptions(memory, input, nsubscriptions)?;
let subscriptions = input_slice let mut events = Vec::new();
.into_iter()
.map(dec_subscription)
.collect::<Result<Vec<_>>>()?;
let output_slice = dec_slice_of_mut::<wasm32::__wasi_event_t>(memory, output, nsubscriptions)?;
let mut output_slice_iter = output_slice.iter_mut();
let mut events_count = 0;
let mut timeout: Option<ClockEventData> = None; let mut timeout: Option<ClockEventData> = None;
let mut fd_events = Vec::new(); let mut fd_events = Vec::new();
for subscription in subscriptions { for subscription in subscriptions {
match subscription.type_ { match subscription.type_ {
host::__WASI_EVENTTYPE_CLOCK => { wasi::__WASI_EVENTTYPE_CLOCK => {
let clock = unsafe { subscription.u.clock }; let clock = unsafe { subscription.u.clock };
let delay = wasi_clock_to_relative_ns_delay(clock)?; let delay = wasi_clock_to_relative_ns_delay(clock)?;
@@ -243,14 +235,14 @@ pub(crate) fn poll_oneoff(
} }
} }
type_ type_
if type_ == host::__WASI_EVENTTYPE_FD_READ if type_ == wasi::__WASI_EVENTTYPE_FD_READ
|| type_ == host::__WASI_EVENTTYPE_FD_WRITE => || type_ == wasi::__WASI_EVENTTYPE_FD_WRITE =>
{ {
let wasi_fd = unsafe { subscription.u.fd_readwrite.fd }; let wasi_fd = unsafe { subscription.u.fd_readwrite.fd };
let rights = if type_ == host::__WASI_EVENTTYPE_FD_READ { let rights = if type_ == wasi::__WASI_EVENTTYPE_FD_READ {
host::__WASI_RIGHT_FD_READ wasi::__WASI_RIGHT_FD_READ
} else { } else {
host::__WASI_RIGHT_FD_WRITE wasi::__WASI_RIGHT_FD_WRITE
}; };
match unsafe { match unsafe {
@@ -264,22 +256,20 @@ pub(crate) fn poll_oneoff(
userdata: subscription.userdata, userdata: subscription.userdata,
}), }),
Err(err) => { Err(err) => {
let event = host::__wasi_event_t { let event = wasi::__wasi_event_t {
userdata: subscription.userdata, userdata: subscription.userdata,
type_, type_,
error: err.as_wasi_errno(), error: err.as_wasi_errno(),
u: host::__wasi_event_t___wasi_event_u { u: wasi::__wasi_event_t___wasi_event_u {
fd_readwrite: host::__wasi_event_t___wasi_event_u___wasi_event_u_fd_readwrite_t { fd_readwrite: wasi::__wasi_event_t___wasi_event_u___wasi_event_u_fd_readwrite_t {
nbytes: 0, nbytes: 0,
flags: 0, flags: 0,
} __bindgen_padding_0: [0, 0, 0],
} },
},
__bindgen_padding_0: 0,
}; };
*output_slice_iter events.push(event);
.next()
.expect("number of subscriptions has to match number of events") =
enc_event(event);
events_count += 1;
} }
}; };
} }
@@ -290,25 +280,23 @@ pub(crate) fn poll_oneoff(
log::debug!("poll_oneoff timeout = {:?}", timeout); log::debug!("poll_oneoff timeout = {:?}", timeout);
log::debug!("poll_oneoff fd_events = {:?}", fd_events); log::debug!("poll_oneoff fd_events = {:?}", fd_events);
let events = hostcalls_impl::poll_oneoff(timeout, fd_events)?; hostcalls_impl::poll_oneoff(timeout, fd_events, &mut events)?;
events_count += events.len();
for event in events { let events_count = u32::try_from(events.len()).map_err(|_| Error::EOVERFLOW)?;
*output_slice_iter
.next() enc_events(memory, output, nsubscriptions, events)?;
.expect("number of subscriptions has to match number of events") = enc_event(event);
}
trace!(" | *nevents={:?}", events_count); trace!(" | *nevents={:?}", events_count);
enc_pointee(memory, nevents, events_count) enc_int_byref(memory, nevents, events_count)
} }
fn wasi_clock_to_relative_ns_delay( fn wasi_clock_to_relative_ns_delay(
wasi_clock: host::__wasi_subscription_t___wasi_subscription_u___wasi_subscription_u_clock_t, wasi_clock: wasi::__wasi_subscription_t___wasi_subscription_u___wasi_subscription_u_clock_t,
) -> Result<u128> { ) -> Result<u128> {
use std::time::SystemTime; use std::time::SystemTime;
if wasi_clock.flags != host::__WASI_SUBSCRIPTION_CLOCK_ABSTIME { if wasi_clock.flags != wasi::__WASI_SUBSCRIPTION_CLOCK_ABSTIME {
return Ok(u128::from(wasi_clock.timeout)); return Ok(u128::from(wasi_clock.timeout));
} }
let now: u128 = SystemTime::now() let now: u128 = SystemTime::now()
@@ -322,12 +310,12 @@ fn wasi_clock_to_relative_ns_delay(
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone)]
pub(crate) struct ClockEventData { pub(crate) struct ClockEventData {
pub(crate) delay: u128, // delay is expressed in nanoseconds pub(crate) delay: u128, // delay is expressed in nanoseconds
pub(crate) userdata: host::__wasi_userdata_t, pub(crate) userdata: wasi::__wasi_userdata_t,
} }
#[derive(Debug)] #[derive(Debug)]
pub(crate) struct FdEventData<'a> { pub(crate) struct FdEventData<'a> {
pub(crate) descriptor: &'a Descriptor, pub(crate) descriptor: &'a Descriptor,
pub(crate) type_: host::__wasi_eventtype_t, pub(crate) type_: wasi::__wasi_eventtype_t,
pub(crate) userdata: host::__wasi_userdata_t, pub(crate) userdata: wasi::__wasi_userdata_t,
} }

View File

@@ -32,10 +32,18 @@ pub mod fs;
mod host; mod host;
pub mod hostcalls; pub mod hostcalls;
mod memory; mod memory;
pub mod wasm32; pub mod wasi;
pub mod wasi32;
pub use ctx::{WasiCtx, WasiCtxBuilder}; pub use ctx::{WasiCtx, WasiCtxBuilder};
pub use sys::preopen_dir; pub use sys::preopen_dir;
pub type Error = error::Error; pub type Error = error::Error;
pub(crate) type Result<T> = std::result::Result<T, Error>; pub(crate) type Result<T> = std::result::Result<T, Error>;
// We can remove this once Wasmtime is updated.
#[deprecated = "wasm32 is deprecated; use wasi or wasi32 instead"]
pub mod wasm32 {
pub use crate::wasi::*;
pub use crate::wasi32::*;
}

View File

@@ -3,11 +3,11 @@ macro_rules! hostcalls {
#[wasi_common_cbindgen::wasi_common_cbindgen] #[wasi_common_cbindgen::wasi_common_cbindgen]
pub unsafe fn $name($($arg: $ty,)*) -> $ret { pub unsafe fn $name($($arg: $ty,)*) -> $ret {
let ret = match crate::hostcalls_impl::$name($($arg,)*) { let ret = match crate::hostcalls_impl::$name($($arg,)*) {
Ok(()) => crate::host::__WASI_ESUCCESS, Ok(()) => crate::wasi::__WASI_ESUCCESS,
Err(e) => e.as_wasi_errno(), Err(e) => e.as_wasi_errno(),
}; };
crate::hostcalls::return_enc_errno(ret) ret
} }
)*) )*)
} }

View File

@@ -1,11 +1,20 @@
//! Functions to go back and forth between WASI types in host and wasm32 representations. //! Functions to store and load data to and from wasm linear memory,
//! transforming them from and to host data types.
//!
//! Endianness concerns are completely encapsulated in this file, so
//! that users outside this file holding a `wasi::*` value never need
//! to consider what endianness it's in. Inside this file,
//! wasm linear-memory-ordered values are called "raw" values, and
//! are not held for long durations.
#![allow(unused)] #![allow(unused)]
use crate::{host, wasm32, Error, Result}; use crate::{host, wasi, wasi32, Error, Result};
use num::PrimInt;
use std::convert::TryFrom; use std::convert::TryFrom;
use std::mem::{align_of, size_of}; use std::mem::{align_of, size_of};
use std::{ptr, slice}; use std::{ptr, slice};
fn dec_ptr(memory: &[u8], ptr: wasm32::uintptr_t, len: usize) -> Result<*const u8> { fn dec_ptr(memory: &[u8], ptr: wasi32::uintptr_t, len: usize) -> Result<*const u8> {
// check for overflow // check for overflow
let checked_len = (ptr as usize).checked_add(len).ok_or(Error::EFAULT)?; let checked_len = (ptr as usize).checked_add(len).ok_or(Error::EFAULT)?;
@@ -16,7 +25,7 @@ fn dec_ptr(memory: &[u8], ptr: wasm32::uintptr_t, len: usize) -> Result<*const u
.map(|mem| mem.as_ptr()) .map(|mem| mem.as_ptr())
} }
fn dec_ptr_mut(memory: &mut [u8], ptr: wasm32::uintptr_t, len: usize) -> Result<*mut u8> { fn dec_ptr_mut(memory: &mut [u8], ptr: wasi32::uintptr_t, len: usize) -> Result<*mut u8> {
// check for overflow // check for overflow
let checked_len = (ptr as usize).checked_add(len).ok_or(Error::EFAULT)?; let checked_len = (ptr as usize).checked_add(len).ok_or(Error::EFAULT)?;
@@ -27,7 +36,7 @@ fn dec_ptr_mut(memory: &mut [u8], ptr: wasm32::uintptr_t, len: usize) -> Result<
.map(|mem| mem.as_mut_ptr()) .map(|mem| mem.as_mut_ptr())
} }
fn dec_ptr_to<'memory, T>(memory: &'memory [u8], ptr: wasm32::uintptr_t) -> Result<&'memory T> { fn dec_ptr_to<'memory, T>(memory: &'memory [u8], ptr: wasi32::uintptr_t) -> Result<&'memory T> {
// check that the ptr is aligned // check that the ptr is aligned
if ptr as usize % align_of::<T>() != 0 { if ptr as usize % align_of::<T>() != 0 {
return Err(Error::EINVAL); return Err(Error::EINVAL);
@@ -38,7 +47,7 @@ fn dec_ptr_to<'memory, T>(memory: &'memory [u8], ptr: wasm32::uintptr_t) -> Resu
fn dec_ptr_to_mut<'memory, T>( fn dec_ptr_to_mut<'memory, T>(
memory: &'memory mut [u8], memory: &'memory mut [u8],
ptr: wasm32::uintptr_t, ptr: wasi32::uintptr_t,
) -> Result<&'memory mut T> { ) -> Result<&'memory mut T> {
// check that the ptr is aligned // check that the ptr is aligned
if ptr as usize % align_of::<T>() != 0 { if ptr as usize % align_of::<T>() != 0 {
@@ -48,15 +57,31 @@ fn dec_ptr_to_mut<'memory, T>(
dec_ptr_mut(memory, ptr, size_of::<T>()).map(|p| unsafe { &mut *(p as *mut T) }) dec_ptr_mut(memory, ptr, size_of::<T>()).map(|p| unsafe { &mut *(p as *mut T) })
} }
pub(crate) fn dec_pointee<T>(memory: &[u8], ptr: wasm32::uintptr_t) -> Result<T> { /// This function does not perform endianness conversions!
fn dec_raw_byref<T>(memory: &[u8], ptr: wasi32::uintptr_t) -> Result<T> {
dec_ptr_to::<T>(memory, ptr).map(|p| unsafe { ptr::read(p) }) dec_ptr_to::<T>(memory, ptr).map(|p| unsafe { ptr::read(p) })
} }
pub(crate) fn enc_pointee<T>(memory: &mut [u8], ptr: wasm32::uintptr_t, t: T) -> Result<()> { /// This function does not perform endianness conversions!
fn enc_raw_byref<T>(memory: &mut [u8], ptr: wasi32::uintptr_t, t: T) -> Result<()> {
dec_ptr_to_mut::<T>(memory, ptr).map(|p| unsafe { ptr::write(p, t) }) dec_ptr_to_mut::<T>(memory, ptr).map(|p| unsafe { ptr::write(p, t) })
} }
fn check_slice_of<T>(ptr: wasm32::uintptr_t, len: wasm32::size_t) -> Result<(usize, usize)> { pub(crate) fn dec_int_byref<T>(memory: &[u8], ptr: wasi32::uintptr_t) -> Result<T>
where
T: PrimInt,
{
dec_raw_byref::<T>(memory, ptr).map(|i| PrimInt::from_le(i))
}
pub(crate) fn enc_int_byref<T>(memory: &mut [u8], ptr: wasi32::uintptr_t, t: T) -> Result<()>
where
T: PrimInt,
{
enc_raw_byref::<T>(memory, ptr, PrimInt::to_le(t))
}
fn check_slice_of<T>(ptr: wasi32::uintptr_t, len: wasi32::size_t) -> Result<(usize, usize)> {
// check alignment, and that length doesn't overflow // check alignment, and that length doesn't overflow
if ptr as usize % align_of::<T>() != 0 { if ptr as usize % align_of::<T>() != 0 {
return Err(Error::EINVAL); return Err(Error::EINVAL);
@@ -71,31 +96,31 @@ fn check_slice_of<T>(ptr: wasm32::uintptr_t, len: wasm32::size_t) -> Result<(usi
Ok((len, len_bytes)) Ok((len, len_bytes))
} }
pub(crate) fn dec_slice_of<'memory, T>( fn dec_raw_slice_of<'memory, T>(
memory: &'memory [u8], memory: &'memory [u8],
ptr: wasm32::uintptr_t, ptr: wasi32::uintptr_t,
len: wasm32::size_t, len: wasi32::size_t,
) -> Result<&'memory [T]> { ) -> Result<&'memory [T]> {
let (len, len_bytes) = check_slice_of::<T>(ptr, len)?; let (len, len_bytes) = check_slice_of::<T>(ptr, len)?;
let ptr = dec_ptr(memory, ptr, len_bytes)? as *const T; let ptr = dec_ptr(memory, ptr, len_bytes)? as *const T;
Ok(unsafe { slice::from_raw_parts(ptr, len) }) Ok(unsafe { slice::from_raw_parts(ptr, len) })
} }
pub(crate) fn dec_slice_of_mut<'memory, T>( fn dec_raw_slice_of_mut<'memory, T>(
memory: &'memory mut [u8], memory: &'memory mut [u8],
ptr: wasm32::uintptr_t, ptr: wasi32::uintptr_t,
len: wasm32::size_t, len: wasi32::size_t,
) -> Result<&'memory mut [T]> { ) -> Result<&'memory mut [T]> {
let (len, len_bytes) = check_slice_of::<T>(ptr, len)?; let (len, len_bytes) = check_slice_of::<T>(ptr, len)?;
let ptr = dec_ptr_mut(memory, ptr, len_bytes)? as *mut T; let ptr = dec_ptr_mut(memory, ptr, len_bytes)? as *mut T;
Ok(unsafe { slice::from_raw_parts_mut(ptr, len) }) Ok(unsafe { slice::from_raw_parts_mut(ptr, len) })
} }
pub(crate) fn enc_slice_of<T>( fn raw_slice_for_enc<'memory, T>(
memory: &mut [u8], memory: &'memory mut [u8],
slice: &[T], slice: &[T],
ptr: wasm32::uintptr_t, ptr: wasi32::uintptr_t,
) -> Result<()> { ) -> Result<&'memory mut [T]> {
// check alignment // check alignment
if ptr as usize % align_of::<T>() != 0 { if ptr as usize % align_of::<T>() != 0 {
return Err(Error::EINVAL); return Err(Error::EINVAL);
@@ -107,449 +132,353 @@ pub(crate) fn enc_slice_of<T>(
return Err(Error::EOVERFLOW); return Err(Error::EOVERFLOW);
}; };
// get the pointer into guest memory, and copy the bytes // get the pointer into guest memory
let ptr = dec_ptr_mut(memory, ptr, len_bytes)? as *mut libc::c_void; let ptr = dec_ptr_mut(memory, ptr, len_bytes)? as *mut T;
unsafe {
ptr::copy_nonoverlapping(slice.as_ptr() as *const libc::c_void, ptr, len_bytes); Ok(unsafe { slice::from_raw_parts_mut(ptr, slice.len()) })
}
pub(crate) fn dec_slice_of_u8<'memory>(
memory: &'memory [u8],
ptr: wasi32::uintptr_t,
len: wasi32::size_t,
) -> Result<&'memory [u8]> {
dec_raw_slice_of::<u8>(memory, ptr, len)
}
pub(crate) fn dec_slice_of_mut_u8<'memory>(
memory: &'memory mut [u8],
ptr: wasi32::uintptr_t,
len: wasi32::size_t,
) -> Result<&'memory mut [u8]> {
dec_raw_slice_of_mut::<u8>(memory, ptr, len)
}
pub(crate) fn enc_slice_of_u8(
memory: &mut [u8],
slice: &[u8],
ptr: wasi32::uintptr_t,
) -> Result<()> {
let output = raw_slice_for_enc::<u8>(memory, slice, ptr)?;
output.copy_from_slice(slice);
Ok(())
}
pub(crate) fn enc_slice_of_wasi32_uintptr(
memory: &mut [u8],
slice: &[wasi32::uintptr_t],
ptr: wasi32::uintptr_t,
) -> Result<()> {
let mut output_iter = raw_slice_for_enc::<wasi32::uintptr_t>(memory, slice, ptr)?.into_iter();
for p in slice {
*output_iter.next().unwrap() = PrimInt::to_le(*p);
} }
Ok(()) Ok(())
} }
macro_rules! dec_enc_scalar { macro_rules! dec_enc_scalar {
( $ty:ident, $dec:ident, $dec_byref:ident, $enc:ident, $enc_byref:ident) => { ( $ty:ident, $dec_byref:ident, $enc_byref:ident) => {
pub(crate) fn $dec(x: wasm32::$ty) -> host::$ty { pub(crate) fn $dec_byref(memory: &mut [u8], ptr: wasi32::uintptr_t) -> Result<wasi::$ty> {
host::$ty::from_le(x) dec_int_byref::<wasi::$ty>(memory, ptr)
}
pub(crate) fn $dec_byref(memory: &mut [u8], ptr: wasm32::uintptr_t) -> Result<host::$ty> {
dec_pointee::<wasm32::$ty>(memory, ptr).map($dec)
}
pub(crate) fn $enc(x: host::$ty) -> wasm32::$ty {
x.to_le()
} }
pub(crate) fn $enc_byref( pub(crate) fn $enc_byref(
memory: &mut [u8], memory: &mut [u8],
ptr: wasm32::uintptr_t, ptr: wasi32::uintptr_t,
x: host::$ty, x: wasi::$ty,
) -> Result<()> { ) -> Result<()> {
enc_pointee::<wasm32::$ty>(memory, ptr, $enc(x)) enc_int_byref::<wasi::$ty>(memory, ptr, x)
} }
}; };
} }
pub(crate) fn dec_ciovec(
memory: &[u8],
ciovec: &wasm32::__wasi_ciovec_t,
) -> Result<host::__wasi_ciovec_t> {
let len = dec_usize(ciovec.buf_len);
Ok(host::__wasi_ciovec_t {
buf: dec_ptr(memory, ciovec.buf, len)? as *const host::void,
buf_len: len,
})
}
pub(crate) fn dec_ciovec_slice( pub(crate) fn dec_ciovec_slice(
memory: &[u8], memory: &[u8],
ptr: wasm32::uintptr_t, ptr: wasi32::uintptr_t,
len: wasm32::size_t, len: wasi32::size_t,
) -> Result<Vec<host::__wasi_ciovec_t>> { ) -> Result<Vec<host::__wasi_ciovec_t>> {
let slice = dec_slice_of::<wasm32::__wasi_ciovec_t>(memory, ptr, len)?; let raw_slice = dec_raw_slice_of::<wasi32::__wasi_ciovec_t>(memory, ptr, len)?;
slice.iter().map(|iov| dec_ciovec(memory, iov)).collect()
}
pub(crate) fn dec_iovec( raw_slice
memory: &[u8], .iter()
iovec: &wasm32::__wasi_iovec_t, .map(|raw_iov| {
) -> Result<host::__wasi_iovec_t> { let len = dec_usize(PrimInt::from_le(raw_iov.buf_len));
let len = dec_usize(iovec.buf_len); let buf = PrimInt::from_le(raw_iov.buf);
Ok(host::__wasi_iovec_t { Ok(host::__wasi_ciovec_t {
buf: dec_ptr(memory, iovec.buf, len)? as *mut host::void, buf: dec_ptr(memory, buf, len)? as *const host::void,
buf_len: len, buf_len: len,
}) })
})
.collect()
} }
pub(crate) fn dec_iovec_slice( pub(crate) fn dec_iovec_slice(
memory: &[u8], memory: &[u8],
ptr: wasm32::uintptr_t, ptr: wasi32::uintptr_t,
len: wasm32::size_t, len: wasi32::size_t,
) -> Result<Vec<host::__wasi_iovec_t>> { ) -> Result<Vec<host::__wasi_iovec_t>> {
let slice = dec_slice_of::<wasm32::__wasi_iovec_t>(memory, ptr, len)?; let raw_slice = dec_raw_slice_of::<wasi32::__wasi_iovec_t>(memory, ptr, len)?;
slice.iter().map(|iov| dec_iovec(memory, iov)).collect()
raw_slice
.iter()
.map(|raw_iov| {
let len = dec_usize(PrimInt::from_le(raw_iov.buf_len));
let buf = PrimInt::from_le(raw_iov.buf);
Ok(host::__wasi_iovec_t {
buf: dec_ptr(memory, buf, len)? as *mut host::void,
buf_len: len,
})
})
.collect()
} }
dec_enc_scalar!( dec_enc_scalar!(__wasi_clockid_t, dec_clockid_byref, enc_clockid_byref);
__wasi_clockid_t, dec_enc_scalar!(__wasi_errno_t, dec_errno_byref, enc_errno_byref);
dec_clockid, dec_enc_scalar!(__wasi_exitcode_t, dec_exitcode_byref, enc_exitcode_byref);
dec_clockid_byref, dec_enc_scalar!(__wasi_fd_t, dec_fd_byref, enc_fd_byref);
enc_clockid, dec_enc_scalar!(__wasi_fdflags_t, dec_fdflags_byref, enc_fdflags_byref);
enc_clockid_byref dec_enc_scalar!(__wasi_device_t, dev_device_byref, enc_device_byref);
); dec_enc_scalar!(__wasi_inode_t, dev_inode_byref, enc_inode_byref);
dec_enc_scalar!(__wasi_linkcount_t, dev_linkcount_byref, enc_linkcount_byref);
dec_enc_scalar!(
__wasi_errno_t,
dec_errno,
dec_errno_byref,
enc_errno,
enc_errno_byref
);
dec_enc_scalar!(
__wasi_exitcode_t,
dec_exitcode,
dec_exitcode_byref,
enc_exitcode,
enc_exitcode_byref
);
dec_enc_scalar!(__wasi_fd_t, dec_fd, dec_fd_byref, enc_fd, enc_fd_byref);
dec_enc_scalar!(
__wasi_fdflags_t,
dec_fdflags,
dec_fdflags_byref,
enc_fdflags,
enc_fdflags_byref
);
dec_enc_scalar!(
__wasi_device_t,
dec_device,
dev_device_byref,
enc_device,
enc_device_byref
);
dec_enc_scalar!(
__wasi_inode_t,
dec_inode,
dev_inode_byref,
enc_inode,
enc_inode_byref
);
dec_enc_scalar!(
__wasi_linkcount_t,
dec_linkcount,
dev_linkcount_byref,
enc_linkcount,
enc_linkcount_byref
);
pub(crate) fn dec_filestat(filestat: wasm32::__wasi_filestat_t) -> host::__wasi_filestat_t {
host::__wasi_filestat_t {
st_dev: dec_device(filestat.st_dev),
st_ino: dec_inode(filestat.st_ino),
st_filetype: dec_filetype(filestat.st_filetype),
st_nlink: dec_linkcount(filestat.st_nlink),
st_size: dec_filesize(filestat.st_size),
st_atim: dec_timestamp(filestat.st_atim),
st_mtim: dec_timestamp(filestat.st_mtim),
st_ctim: dec_timestamp(filestat.st_ctim),
}
}
pub(crate) fn dec_filestat_byref( pub(crate) fn dec_filestat_byref(
memory: &mut [u8], memory: &mut [u8],
filestat_ptr: wasm32::uintptr_t, filestat_ptr: wasi32::uintptr_t,
) -> Result<host::__wasi_filestat_t> { ) -> Result<wasi::__wasi_filestat_t> {
dec_pointee::<wasm32::__wasi_filestat_t>(memory, filestat_ptr).map(dec_filestat) let raw = dec_raw_byref::<wasi::__wasi_filestat_t>(memory, filestat_ptr)?;
}
pub(crate) fn enc_filestat(filestat: host::__wasi_filestat_t) -> wasm32::__wasi_filestat_t { Ok(wasi::__wasi_filestat_t {
wasm32::__wasi_filestat_t { st_dev: PrimInt::from_le(raw.st_dev),
st_dev: enc_device(filestat.st_dev), st_ino: PrimInt::from_le(raw.st_ino),
st_ino: enc_inode(filestat.st_ino), st_filetype: PrimInt::from_le(raw.st_filetype),
st_filetype: enc_filetype(filestat.st_filetype), st_nlink: PrimInt::from_le(raw.st_nlink),
st_nlink: enc_linkcount(filestat.st_nlink), st_size: PrimInt::from_le(raw.st_size),
st_size: enc_filesize(filestat.st_size), st_atim: PrimInt::from_le(raw.st_atim),
st_atim: enc_timestamp(filestat.st_atim), st_mtim: PrimInt::from_le(raw.st_mtim),
st_mtim: enc_timestamp(filestat.st_mtim), st_ctim: PrimInt::from_le(raw.st_ctim),
st_ctim: enc_timestamp(filestat.st_ctim), })
}
} }
pub(crate) fn enc_filestat_byref( pub(crate) fn enc_filestat_byref(
memory: &mut [u8], memory: &mut [u8],
filestat_ptr: wasm32::uintptr_t, filestat_ptr: wasi32::uintptr_t,
host_filestat: host::__wasi_filestat_t, filestat: wasi::__wasi_filestat_t,
) -> Result<()> { ) -> Result<()> {
let filestat = enc_filestat(host_filestat); let raw = wasi::__wasi_filestat_t {
enc_pointee::<wasm32::__wasi_filestat_t>(memory, filestat_ptr, filestat) st_dev: PrimInt::to_le(filestat.st_dev),
} st_ino: PrimInt::to_le(filestat.st_ino),
st_filetype: PrimInt::to_le(filestat.st_filetype),
st_nlink: PrimInt::to_le(filestat.st_nlink),
st_size: PrimInt::to_le(filestat.st_size),
st_atim: PrimInt::to_le(filestat.st_atim),
st_mtim: PrimInt::to_le(filestat.st_mtim),
st_ctim: PrimInt::to_le(filestat.st_ctim),
};
pub(crate) fn dec_fdstat(fdstat: wasm32::__wasi_fdstat_t) -> host::__wasi_fdstat_t { enc_raw_byref::<wasi::__wasi_filestat_t>(memory, filestat_ptr, raw)
host::__wasi_fdstat_t {
fs_filetype: dec_filetype(fdstat.fs_filetype),
fs_flags: dec_fdflags(fdstat.fs_flags),
fs_rights_base: dec_rights(fdstat.fs_rights_base),
fs_rights_inheriting: dec_rights(fdstat.fs_rights_inheriting),
}
} }
pub(crate) fn dec_fdstat_byref( pub(crate) fn dec_fdstat_byref(
memory: &mut [u8], memory: &mut [u8],
fdstat_ptr: wasm32::uintptr_t, fdstat_ptr: wasi32::uintptr_t,
) -> Result<host::__wasi_fdstat_t> { ) -> Result<wasi::__wasi_fdstat_t> {
dec_pointee::<wasm32::__wasi_fdstat_t>(memory, fdstat_ptr).map(dec_fdstat) let raw = dec_raw_byref::<wasi::__wasi_fdstat_t>(memory, fdstat_ptr)?;
}
pub(crate) fn enc_fdstat(fdstat: host::__wasi_fdstat_t) -> wasm32::__wasi_fdstat_t { Ok(wasi::__wasi_fdstat_t {
wasm32::__wasi_fdstat_t { fs_filetype: PrimInt::from_le(raw.fs_filetype),
fs_filetype: enc_filetype(fdstat.fs_filetype), fs_flags: PrimInt::from_le(raw.fs_flags),
fs_flags: enc_fdflags(fdstat.fs_flags), fs_rights_base: PrimInt::from_le(raw.fs_rights_base),
fs_rights_inheriting: PrimInt::from_le(raw.fs_rights_inheriting),
__bindgen_padding_0: 0, __bindgen_padding_0: 0,
fs_rights_base: enc_rights(fdstat.fs_rights_base), })
fs_rights_inheriting: enc_rights(fdstat.fs_rights_inheriting),
}
} }
pub(crate) fn enc_fdstat_byref( pub(crate) fn enc_fdstat_byref(
memory: &mut [u8], memory: &mut [u8],
fdstat_ptr: wasm32::uintptr_t, fdstat_ptr: wasi32::uintptr_t,
host_fdstat: host::__wasi_fdstat_t, fdstat: wasi::__wasi_fdstat_t,
) -> Result<()> { ) -> Result<()> {
let fdstat = enc_fdstat(host_fdstat); let raw = wasi::__wasi_fdstat_t {
enc_pointee::<wasm32::__wasi_fdstat_t>(memory, fdstat_ptr, fdstat) fs_filetype: PrimInt::to_le(fdstat.fs_filetype),
fs_flags: PrimInt::to_le(fdstat.fs_flags),
__bindgen_padding_0: 0,
fs_rights_base: PrimInt::to_le(fdstat.fs_rights_base),
fs_rights_inheriting: PrimInt::to_le(fdstat.fs_rights_inheriting),
};
enc_raw_byref::<wasi::__wasi_fdstat_t>(memory, fdstat_ptr, raw)
} }
dec_enc_scalar!( dec_enc_scalar!(__wasi_filedelta_t, dec_filedelta_byref, enc_filedelta_byref);
__wasi_filedelta_t, dec_enc_scalar!(__wasi_filesize_t, dec_filesize_byref, enc_filesize_byref);
dec_filedelta, dec_enc_scalar!(__wasi_filetype_t, dec_filetype_byref, enc_filetype_byref);
dec_filedelta_byref,
enc_filedelta,
enc_filedelta_byref
);
dec_enc_scalar!(
__wasi_filesize_t,
dec_filesize,
dec_filesize_byref,
enc_filesize,
enc_filesize_byref
);
dec_enc_scalar!(
__wasi_filetype_t,
dec_filetype,
dec_filetype_byref,
enc_filetype,
enc_filetype_byref
);
dec_enc_scalar!( dec_enc_scalar!(
__wasi_lookupflags_t, __wasi_lookupflags_t,
dec_lookupflags,
dec_lookupflags_byref, dec_lookupflags_byref,
enc_lookupflags,
enc_lookupflags_byref enc_lookupflags_byref
); );
dec_enc_scalar!( dec_enc_scalar!(__wasi_oflags_t, dec_oflags_byref, enc_oflags_byref);
__wasi_oflags_t,
dec_oflags,
dec_oflags_byref,
enc_oflags,
enc_oflags_byref
);
pub(crate) fn dec_prestat(prestat: wasm32::__wasi_prestat_t) -> Result<host::__wasi_prestat_t> {
match prestat.pr_type {
wasm32::__WASI_PREOPENTYPE_DIR => {
let u = host::__wasi_prestat_t___wasi_prestat_u {
dir: host::__wasi_prestat_t___wasi_prestat_u___wasi_prestat_u_dir_t {
pr_name_len: dec_usize(unsafe { prestat.u.dir.pr_name_len }),
},
};
Ok(host::__wasi_prestat_t {
pr_type: host::__WASI_PREOPENTYPE_DIR,
u,
})
}
_ => Err(Error::EINVAL),
}
}
pub(crate) fn dec_prestat_byref( pub(crate) fn dec_prestat_byref(
memory: &mut [u8], memory: &mut [u8],
prestat_ptr: wasm32::uintptr_t, prestat_ptr: wasi32::uintptr_t,
) -> Result<host::__wasi_prestat_t> { ) -> Result<host::__wasi_prestat_t> {
dec_pointee::<wasm32::__wasi_prestat_t>(memory, prestat_ptr).and_then(dec_prestat) let raw = dec_raw_byref::<wasi32::__wasi_prestat_t>(memory, prestat_ptr)?;
}
pub(crate) fn enc_prestat(prestat: host::__wasi_prestat_t) -> Result<wasm32::__wasi_prestat_t> { match PrimInt::from_le(raw.pr_type) {
match prestat.pr_type { wasi::__WASI_PREOPENTYPE_DIR => Ok(host::__wasi_prestat_t {
host::__WASI_PREOPENTYPE_DIR => { pr_type: wasi::__WASI_PREOPENTYPE_DIR,
let u = wasm32::__wasi_prestat_t___wasi_prestat_u { u: host::__wasi_prestat_t___wasi_prestat_u {
dir: wasm32::__wasi_prestat_t___wasi_prestat_u___wasi_prestat_u_dir_t { dir: host::__wasi_prestat_t___wasi_prestat_u___wasi_prestat_u_dir_t {
pr_name_len: enc_usize(unsafe { prestat.u.dir.pr_name_len }), pr_name_len: dec_usize(PrimInt::from_le(unsafe { raw.u.dir.pr_name_len })),
}, },
}; },
Ok(wasm32::__wasi_prestat_t { }),
pr_type: wasm32::__WASI_PREOPENTYPE_DIR,
u,
})
}
_ => Err(Error::EINVAL), _ => Err(Error::EINVAL),
} }
} }
pub(crate) fn enc_prestat_byref( pub(crate) fn enc_prestat_byref(
memory: &mut [u8], memory: &mut [u8],
prestat_ptr: wasm32::uintptr_t, prestat_ptr: wasi32::uintptr_t,
host_prestat: host::__wasi_prestat_t, prestat: host::__wasi_prestat_t,
) -> Result<()> { ) -> Result<()> {
let prestat = enc_prestat(host_prestat)?; let raw = match prestat.pr_type {
enc_pointee::<wasm32::__wasi_prestat_t>(memory, prestat_ptr, prestat) wasi::__WASI_PREOPENTYPE_DIR => Ok(wasi32::__wasi_prestat_t {
pr_type: PrimInt::to_le(wasi::__WASI_PREOPENTYPE_DIR),
u: wasi32::__wasi_prestat_t___wasi_prestat_u {
dir: wasi32::__wasi_prestat_t___wasi_prestat_u___wasi_prestat_u_dir_t {
pr_name_len: enc_usize(unsafe { prestat.u.dir.pr_name_len }),
},
},
}),
_ => Err(Error::EINVAL),
}?;
enc_raw_byref::<wasi32::__wasi_prestat_t>(memory, prestat_ptr, raw)
} }
dec_enc_scalar!( dec_enc_scalar!(__wasi_rights_t, dec_rights_byref, enc_rights_byref);
__wasi_rights_t, dec_enc_scalar!(__wasi_timestamp_t, dec_timestamp_byref, enc_timestamp_byref);
dec_rights,
dec_rights_byref,
enc_rights,
enc_rights_byref
);
dec_enc_scalar!( pub(crate) fn dec_usize(size: wasi32::size_t) -> usize {
__wasi_timestamp_t, usize::try_from(size).unwrap()
dec_timestamp,
dec_timestamp_byref,
enc_timestamp,
enc_timestamp_byref
);
pub(crate) fn dec_u32(x: u32) -> u32 {
u32::from_le(x)
} }
pub(crate) fn enc_u32(x: u32) -> u32 { pub(crate) fn enc_usize(size: usize) -> wasi32::size_t {
x.to_le() wasi32::size_t::try_from(size).unwrap()
}
pub(crate) fn dec_usize(size: wasm32::size_t) -> usize {
usize::try_from(u32::from_le(size)).unwrap()
}
pub(crate) fn enc_usize(size: usize) -> wasm32::size_t {
wasm32::size_t::try_from(size).unwrap()
} }
pub(crate) fn enc_usize_byref( pub(crate) fn enc_usize_byref(
memory: &mut [u8], memory: &mut [u8],
usize_ptr: wasm32::uintptr_t, usize_ptr: wasi32::uintptr_t,
host_usize: usize, host_usize: usize,
) -> Result<()> { ) -> Result<()> {
enc_pointee::<wasm32::size_t>(memory, usize_ptr, enc_usize(host_usize)) enc_int_byref::<wasi32::size_t>(memory, usize_ptr, enc_usize(host_usize))
} }
dec_enc_scalar!( dec_enc_scalar!(__wasi_whence_t, dec_whence_byref, enc_whence_byref);
__wasi_whence_t,
dec_whence,
dec_whence_byref,
enc_whence,
enc_whence_byref
);
dec_enc_scalar!( dec_enc_scalar!(
__wasi_subclockflags_t, __wasi_subclockflags_t,
dec_subclockflags,
dec_subclockflags_byref, dec_subclockflags_byref,
enc_subclockflags,
enc_subclockflags_byref enc_subclockflags_byref
); );
dec_enc_scalar!( dec_enc_scalar!(
__wasi_eventrwflags_t, __wasi_eventrwflags_t,
dec_eventrwflags,
dec_eventrwflags_byref, dec_eventrwflags_byref,
enc_eventrwflags,
enc_eventrwflags_byref enc_eventrwflags_byref
); );
dec_enc_scalar!( dec_enc_scalar!(__wasi_eventtype_t, dec_eventtype_byref, enc_eventtype_byref);
__wasi_eventtype_t, dec_enc_scalar!(__wasi_userdata_t, dec_userdata_byref, enc_userdata_byref);
dec_eventtype,
dec_eventtype_byref,
enc_eventtype,
enc_eventtype_byref
);
dec_enc_scalar!( pub(crate) fn dec_subscriptions(
__wasi_userdata_t, memory: &mut [u8],
dec_userdata, input: wasi32::uintptr_t,
dec_userdata_byref, nsubscriptions: wasi32::size_t,
enc_userdata, ) -> Result<Vec<wasi::__wasi_subscription_t>> {
enc_userdata_byref let raw_input_slice =
); dec_raw_slice_of::<wasi::__wasi_subscription_t>(memory, input, nsubscriptions)?;
pub(crate) fn dec_subscription( raw_input_slice
subscription: &wasm32::__wasi_subscription_t, .into_iter()
) -> Result<host::__wasi_subscription_t> { .map(|raw_subscription|{
let userdata = dec_userdata(subscription.userdata); let userdata = PrimInt::from_le(raw_subscription.userdata);
let type_ = dec_eventtype(subscription.type_); let type_ = PrimInt::from_le(raw_subscription.type_);
let u_orig = subscription.u; let raw_u = raw_subscription.u;
let u = match type_ { let u = match type_ {
wasm32::__WASI_EVENTTYPE_CLOCK => host::__wasi_subscription_t___wasi_subscription_u { wasi::__WASI_EVENTTYPE_CLOCK => wasi::__wasi_subscription_t___wasi_subscription_u {
clock: unsafe { clock: unsafe {
host::__wasi_subscription_t___wasi_subscription_u___wasi_subscription_u_clock_t { wasi::__wasi_subscription_t___wasi_subscription_u___wasi_subscription_u_clock_t {
identifier: dec_userdata(u_orig.clock.identifier), identifier: PrimInt::from_le(raw_u.clock.identifier),
clock_id: dec_clockid(u_orig.clock.clock_id), clock_id: PrimInt::from_le(raw_u.clock.clock_id),
timeout: dec_timestamp(u_orig.clock.timeout), timeout: PrimInt::from_le(raw_u.clock.timeout),
precision: dec_timestamp(u_orig.clock.precision), precision: PrimInt::from_le(raw_u.clock.precision),
flags: dec_subclockflags(u_orig.clock.flags), flags: PrimInt::from_le(raw_u.clock.flags),
__bindgen_padding_0: 0,
__bindgen_padding_1: [0,0,0],
} }
}, },
}, },
wasm32::__WASI_EVENTTYPE_FD_READ | wasm32::__WASI_EVENTTYPE_FD_WRITE => host::__wasi_subscription_t___wasi_subscription_u { wasi::__WASI_EVENTTYPE_FD_READ | wasi::__WASI_EVENTTYPE_FD_WRITE => wasi::__wasi_subscription_t___wasi_subscription_u {
fd_readwrite: host::__wasi_subscription_t___wasi_subscription_u___wasi_subscription_u_fd_readwrite_t { fd_readwrite: wasi::__wasi_subscription_t___wasi_subscription_u___wasi_subscription_u_fd_readwrite_t {
fd: dec_fd(unsafe{u_orig.fd_readwrite.fd}) fd: PrimInt::from_le(unsafe{raw_u.fd_readwrite.fd})
} }
}, },
_ => return Err(Error::EINVAL) _ => return Err(Error::EINVAL)
}; };
Ok(host::__wasi_subscription_t { userdata, type_, u }) Ok(wasi::__wasi_subscription_t {
userdata,
type_,
u,
__bindgen_padding_0: 0,
})
})
.collect::<Result<Vec<_>>>()
} }
pub(crate) fn enc_event(event: host::__wasi_event_t) -> wasm32::__wasi_event_t { pub(crate) fn enc_events(
memory: &mut [u8],
output: wasi32::uintptr_t,
nsubscriptions: wasi32::size_t,
events: Vec<wasi::__wasi_event_t>,
) -> Result<()> {
let mut raw_output_iter =
dec_raw_slice_of_mut::<wasi::__wasi_event_t>(memory, output, nsubscriptions)?.into_iter();
for event in events.iter() {
*raw_output_iter
.next()
.expect("the number of events cannot exceed the number of subscriptions") = {
let fd_readwrite = unsafe { event.u.fd_readwrite }; let fd_readwrite = unsafe { event.u.fd_readwrite };
wasm32::__wasi_event_t { wasi::__wasi_event_t {
userdata: enc_userdata(event.userdata), userdata: PrimInt::to_le(event.userdata),
type_: enc_eventtype(event.type_), type_: PrimInt::to_le(event.type_),
error: enc_errno(event.error), error: PrimInt::to_le(event.error),
u: wasm32::__wasi_event_t___wasi_event_u { u: wasi::__wasi_event_t___wasi_event_u {
fd_readwrite: wasm32::__wasi_event_t___wasi_event_u___wasi_event_u_fd_readwrite_t { fd_readwrite:
nbytes: enc_filesize(fd_readwrite.nbytes), wasi::__wasi_event_t___wasi_event_u___wasi_event_u_fd_readwrite_t {
flags: enc_eventrwflags(fd_readwrite.flags), nbytes: PrimInt::to_le(fd_readwrite.nbytes),
flags: PrimInt::to_le(fd_readwrite.flags),
__bindgen_padding_0: [0; 3], __bindgen_padding_0: [0; 3],
}, },
}, },
__bindgen_padding_0: 0, __bindgen_padding_0: 0,
} }
};
}
Ok(())
} }
dec_enc_scalar!( dec_enc_scalar!(__wasi_advice_t, dec_advice_byref, enc_advice_byref);
__wasi_advice_t, dec_enc_scalar!(__wasi_fstflags_t, dec_fstflags_byref, enc_fstflags_byref);
dec_advice, dec_enc_scalar!(__wasi_dircookie_t, dec_dircookie_byref, enc_dircookie_byref);
dec_advice_byref,
enc_advice,
enc_advice_byref
);
dec_enc_scalar!(
__wasi_fstflags_t,
dec_fstflags,
dec_fstflags_byref,
enc_fstflags,
enc_fstflags_byref
);
dec_enc_scalar!(
__wasi_dircookie_t,
dec_dircookie,
dec_dircookie_byref,
enc_dircookie,
enc_dircookie_byref
);

View File

@@ -1,4 +1,4 @@
use crate::host; use crate::wasi;
use cfg_if::cfg_if; use cfg_if::cfg_if;
cfg_if! { cfg_if! {
@@ -7,7 +7,7 @@ cfg_if! {
pub(crate) use self::unix::*; pub(crate) use self::unix::*;
pub use self::unix::preopen_dir; pub use self::unix::preopen_dir;
pub(crate) fn errno_from_host(err: i32) -> host::__wasi_errno_t { pub(crate) fn errno_from_host(err: i32) -> wasi::__wasi_errno_t {
host_impl::errno_from_nix(nix::errno::from_i32(err)).as_wasi_errno() host_impl::errno_from_nix(nix::errno::from_i32(err)).as_wasi_errno()
} }
} else if #[cfg(windows)] { } else if #[cfg(windows)] {
@@ -15,7 +15,7 @@ cfg_if! {
pub(crate) use self::windows::*; pub(crate) use self::windows::*;
pub use self::windows::preopen_dir; pub use self::windows::preopen_dir;
pub(crate) fn errno_from_host(err: i32) -> host::__wasi_errno_t { pub(crate) fn errno_from_host(err: i32) -> wasi::__wasi_errno_t {
host_impl::errno_from_win(winx::winerror::WinError::from_u32(err as u32)) host_impl::errno_from_win(winx::winerror::WinError::from_u32(err as u32))
} }
} else { } else {

View File

@@ -2,7 +2,7 @@ use super::osfile::OsFile;
use crate::hostcalls_impl::PathGet; use crate::hostcalls_impl::PathGet;
use crate::sys::host_impl; use crate::sys::host_impl;
use crate::sys::unix::str_to_cstring; use crate::sys::unix::str_to_cstring;
use crate::{host, Error, Result}; use crate::{wasi, Error, Result};
use nix::libc::{self, c_long, c_void}; use nix::libc::{self, c_long, c_void};
use std::convert::TryInto; use std::convert::TryInto;
use std::fs::File; use std::fs::File;
@@ -142,7 +142,7 @@ pub(crate) fn path_rename(resolved_old: PathGet, resolved_new: PathGet) -> Resul
pub(crate) fn fd_readdir( pub(crate) fn fd_readdir(
os_file: &mut OsFile, os_file: &mut OsFile,
host_buf: &mut [u8], host_buf: &mut [u8],
cookie: host::__wasi_dircookie_t, cookie: wasi::__wasi_dircookie_t,
) -> Result<usize> { ) -> Result<usize> {
use crate::sys::unix::bsd::osfile::DirStream; use crate::sys::unix::bsd::osfile::DirStream;
use libc::{fdopendir, readdir, rewinddir, seekdir, telldir}; use libc::{fdopendir, readdir, rewinddir, seekdir, telldir};
@@ -166,7 +166,7 @@ pub(crate) fn fd_readdir(
let host_buf_ptr = host_buf.as_mut_ptr(); let host_buf_ptr = host_buf.as_mut_ptr();
let host_buf_len = host_buf.len(); let host_buf_len = host_buf.len();
if cookie != host::__WASI_DIRCOOKIE_START { if cookie != wasi::__WASI_DIRCOOKIE_START {
unsafe { seekdir(dir_stream.dir_ptr, cookie as c_long) }; unsafe { seekdir(dir_stream.dir_ptr, cookie as c_long) };
} else { } else {
unsafe { rewinddir(dir_stream.dir_ptr) }; unsafe { rewinddir(dir_stream.dir_ptr) };
@@ -189,13 +189,13 @@ pub(crate) fn fd_readdir(
} }
} }
let mut entry: host::__wasi_dirent_t = let mut entry: wasi::__wasi_dirent_t =
host_impl::dirent_from_host(&unsafe { *host_entry })?; host_impl::dirent_from_host(&unsafe { *host_entry })?;
// Set d_next manually: // Set d_next manually:
// * on macOS d_seekoff is not set for some reason // * on macOS d_seekoff is not set for some reason
// * on FreeBSD d_seekoff doesn't exist; there is d_off but it is // * on FreeBSD d_seekoff doesn't exist; there is d_off but it is
// not equivalent to the value read from telldir call // not equivalent to the value read from telldir call
entry.d_next = unsafe { telldir(dir_stream.dir_ptr) } as host::__wasi_dircookie_t; entry.d_next = unsafe { telldir(dir_stream.dir_ptr) } as wasi::__wasi_dircookie_t;
log::debug!("fd_readdir entry = {:?}", entry); log::debug!("fd_readdir entry = {:?}", entry);
@@ -206,7 +206,7 @@ pub(crate) fn fd_readdir(
} }
unsafe { unsafe {
let ptr = host_buf_ptr.offset(host_buf_offset.try_into()?) as *mut c_void let ptr = host_buf_ptr.offset(host_buf_offset.try_into()?) as *mut c_void
as *mut host::__wasi_dirent_t; as *mut wasi::__wasi_dirent_t;
*ptr = entry; *ptr = entry;
} }
host_buf_offset += std::mem::size_of_val(&entry); host_buf_offset += std::mem::size_of_val(&entry);
@@ -228,21 +228,21 @@ pub(crate) fn fd_readdir(
#[cfg(any(target_os = "macos", target_os = "ios"))] #[cfg(any(target_os = "macos", target_os = "ios"))]
pub(crate) fn fd_advise( pub(crate) fn fd_advise(
file: &File, file: &File,
advice: host::__wasi_advice_t, advice: wasi::__wasi_advice_t,
offset: host::__wasi_filesize_t, offset: wasi::__wasi_filesize_t,
len: host::__wasi_filesize_t, len: wasi::__wasi_filesize_t,
) -> Result<()> { ) -> Result<()> {
use nix::errno::Errno; use nix::errno::Errno;
match advice { match advice {
host::__WASI_ADVICE_DONTNEED => return Ok(()), wasi::__WASI_ADVICE_DONTNEED => return Ok(()),
// unfortunately, the advisory syscall in macOS doesn't take any flags of this // unfortunately, the advisory syscall in macOS doesn't take any flags of this
// sort (unlike on Linux), hence, they are left here as a noop // sort (unlike on Linux), hence, they are left here as a noop
host::__WASI_ADVICE_SEQUENTIAL wasi::__WASI_ADVICE_SEQUENTIAL
| host::__WASI_ADVICE_WILLNEED | wasi::__WASI_ADVICE_WILLNEED
| host::__WASI_ADVICE_NOREUSE | wasi::__WASI_ADVICE_NOREUSE
| host::__WASI_ADVICE_RANDOM | wasi::__WASI_ADVICE_RANDOM
| host::__WASI_ADVICE_NORMAL => {} | wasi::__WASI_ADVICE_NORMAL => {}
_ => return Err(Error::EINVAL), _ => return Err(Error::EINVAL),
} }
@@ -271,17 +271,17 @@ pub(crate) fn fd_advise(
#[cfg(not(any(target_os = "macos", target_os = "ios")))] #[cfg(not(any(target_os = "macos", target_os = "ios")))]
pub(crate) fn fd_advise( pub(crate) fn fd_advise(
_file: &File, _file: &File,
advice: host::__wasi_advice_t, advice: wasi::__wasi_advice_t,
_offset: host::__wasi_filesize_t, _offset: wasi::__wasi_filesize_t,
_len: host::__wasi_filesize_t, _len: wasi::__wasi_filesize_t,
) -> Result<()> { ) -> Result<()> {
match advice { match advice {
host::__WASI_ADVICE_DONTNEED wasi::__WASI_ADVICE_DONTNEED
| host::__WASI_ADVICE_SEQUENTIAL | wasi::__WASI_ADVICE_SEQUENTIAL
| host::__WASI_ADVICE_WILLNEED | wasi::__WASI_ADVICE_WILLNEED
| host::__WASI_ADVICE_NOREUSE | wasi::__WASI_ADVICE_NOREUSE
| host::__WASI_ADVICE_RANDOM | wasi::__WASI_ADVICE_RANDOM
| host::__WASI_ADVICE_NORMAL => {} | wasi::__WASI_ADVICE_NORMAL => {}
_ => return Err(Error::EINVAL), _ => return Err(Error::EINVAL),
} }

View File

@@ -20,19 +20,19 @@ pub(crate) mod fdentry_impl {
pub(crate) mod host_impl { pub(crate) mod host_impl {
use super::super::host_impl::dirent_filetype_from_host; use super::super::host_impl::dirent_filetype_from_host;
use crate::{host, memory, Result}; use crate::{wasi, Result};
pub(crate) const O_RSYNC: nix::fcntl::OFlag = nix::fcntl::OFlag::O_SYNC; pub(crate) const O_RSYNC: nix::fcntl::OFlag = nix::fcntl::OFlag::O_SYNC;
pub(crate) fn dirent_from_host( pub(crate) fn dirent_from_host(
host_entry: &nix::libc::dirent, host_entry: &nix::libc::dirent,
) -> Result<host::__wasi_dirent_t> { ) -> Result<wasi::__wasi_dirent_t> {
let mut entry = unsafe { std::mem::zeroed::<host::__wasi_dirent_t>() }; let mut entry = unsafe { std::mem::zeroed::<wasi::__wasi_dirent_t>() };
let d_type = dirent_filetype_from_host(host_entry)?; let d_type = dirent_filetype_from_host(host_entry)?;
entry.d_ino = memory::enc_inode(host_entry.d_ino); entry.d_ino = host_entry.d_ino;
entry.d_next = memory::enc_dircookie(host_entry.d_seekoff); entry.d_next = host_entry.d_seekoff;
entry.d_namlen = memory::enc_u32(u32::from(host_entry.d_namlen)); entry.d_namlen = u32::from(host_entry.d_namlen);
entry.d_type = memory::enc_filetype(d_type); entry.d_type = d_type;
Ok(entry) Ok(entry)
} }
} }

View File

@@ -1,5 +1,5 @@
use crate::fdentry::Descriptor; use crate::fdentry::Descriptor;
use crate::{host, Error, Result}; use crate::{wasi, Error, Result};
use std::io; use std::io;
use std::os::unix::prelude::{AsRawFd, FileTypeExt, FromRawFd, RawFd}; use std::os::unix::prelude::{AsRawFd, FileTypeExt, FromRawFd, RawFd};
@@ -35,9 +35,9 @@ impl AsRawFd for Descriptor {
pub(crate) unsafe fn determine_type_and_access_rights<Fd: AsRawFd>( pub(crate) unsafe fn determine_type_and_access_rights<Fd: AsRawFd>(
fd: &Fd, fd: &Fd,
) -> Result<( ) -> Result<(
host::__wasi_filetype_t, wasi::__wasi_filetype_t,
host::__wasi_rights_t, wasi::__wasi_rights_t,
host::__wasi_rights_t, wasi::__wasi_rights_t,
)> { )> {
let (file_type, mut rights_base, rights_inheriting) = determine_type_rights(fd)?; let (file_type, mut rights_base, rights_inheriting) = determine_type_rights(fd)?;
@@ -46,9 +46,9 @@ pub(crate) unsafe fn determine_type_and_access_rights<Fd: AsRawFd>(
let flags = OFlag::from_bits_truncate(flags_bits); let flags = OFlag::from_bits_truncate(flags_bits);
let accmode = flags & OFlag::O_ACCMODE; let accmode = flags & OFlag::O_ACCMODE;
if accmode == OFlag::O_RDONLY { if accmode == OFlag::O_RDONLY {
rights_base &= !host::__WASI_RIGHT_FD_WRITE; rights_base &= !wasi::__WASI_RIGHT_FD_WRITE;
} else if accmode == OFlag::O_WRONLY { } else if accmode == OFlag::O_WRONLY {
rights_base &= !host::__WASI_RIGHT_FD_READ; rights_base &= !wasi::__WASI_RIGHT_FD_READ;
} }
Ok((file_type, rights_base, rights_inheriting)) Ok((file_type, rights_base, rights_inheriting))
@@ -58,9 +58,9 @@ pub(crate) unsafe fn determine_type_and_access_rights<Fd: AsRawFd>(
pub(crate) unsafe fn determine_type_rights<Fd: AsRawFd>( pub(crate) unsafe fn determine_type_rights<Fd: AsRawFd>(
fd: &Fd, fd: &Fd,
) -> Result<( ) -> Result<(
host::__wasi_filetype_t, wasi::__wasi_filetype_t,
host::__wasi_rights_t, wasi::__wasi_rights_t,
host::__wasi_rights_t, wasi::__wasi_rights_t,
)> { )> {
let (file_type, rights_base, rights_inheriting) = { let (file_type, rights_base, rights_inheriting) = {
// we just make a `File` here for convenience; we don't want it to close when it drops // we just make a `File` here for convenience; we don't want it to close when it drops
@@ -69,61 +69,61 @@ pub(crate) unsafe fn determine_type_rights<Fd: AsRawFd>(
if ft.is_block_device() { if ft.is_block_device() {
log::debug!("Host fd {:?} is a block device", fd.as_raw_fd()); log::debug!("Host fd {:?} is a block device", fd.as_raw_fd());
( (
host::__WASI_FILETYPE_BLOCK_DEVICE, wasi::__WASI_FILETYPE_BLOCK_DEVICE,
host::RIGHTS_BLOCK_DEVICE_BASE, wasi::RIGHTS_BLOCK_DEVICE_BASE,
host::RIGHTS_BLOCK_DEVICE_INHERITING, wasi::RIGHTS_BLOCK_DEVICE_INHERITING,
) )
} else if ft.is_char_device() { } else if ft.is_char_device() {
log::debug!("Host fd {:?} is a char device", fd.as_raw_fd()); log::debug!("Host fd {:?} is a char device", fd.as_raw_fd());
if isatty(fd)? { if isatty(fd)? {
( (
host::__WASI_FILETYPE_CHARACTER_DEVICE, wasi::__WASI_FILETYPE_CHARACTER_DEVICE,
host::RIGHTS_TTY_BASE, wasi::RIGHTS_TTY_BASE,
host::RIGHTS_TTY_BASE, wasi::RIGHTS_TTY_BASE,
) )
} else { } else {
( (
host::__WASI_FILETYPE_CHARACTER_DEVICE, wasi::__WASI_FILETYPE_CHARACTER_DEVICE,
host::RIGHTS_CHARACTER_DEVICE_BASE, wasi::RIGHTS_CHARACTER_DEVICE_BASE,
host::RIGHTS_CHARACTER_DEVICE_INHERITING, wasi::RIGHTS_CHARACTER_DEVICE_INHERITING,
) )
} }
} else if ft.is_dir() { } else if ft.is_dir() {
log::debug!("Host fd {:?} is a directory", fd.as_raw_fd()); log::debug!("Host fd {:?} is a directory", fd.as_raw_fd());
( (
host::__WASI_FILETYPE_DIRECTORY, wasi::__WASI_FILETYPE_DIRECTORY,
host::RIGHTS_DIRECTORY_BASE, wasi::RIGHTS_DIRECTORY_BASE,
host::RIGHTS_DIRECTORY_INHERITING, wasi::RIGHTS_DIRECTORY_INHERITING,
) )
} else if ft.is_file() { } else if ft.is_file() {
log::debug!("Host fd {:?} is a file", fd.as_raw_fd()); log::debug!("Host fd {:?} is a file", fd.as_raw_fd());
( (
host::__WASI_FILETYPE_REGULAR_FILE, wasi::__WASI_FILETYPE_REGULAR_FILE,
host::RIGHTS_REGULAR_FILE_BASE, wasi::RIGHTS_REGULAR_FILE_BASE,
host::RIGHTS_REGULAR_FILE_INHERITING, wasi::RIGHTS_REGULAR_FILE_INHERITING,
) )
} else if ft.is_socket() { } else if ft.is_socket() {
log::debug!("Host fd {:?} is a socket", fd.as_raw_fd()); log::debug!("Host fd {:?} is a socket", fd.as_raw_fd());
use nix::sys::socket; use nix::sys::socket;
match socket::getsockopt(fd.as_raw_fd(), socket::sockopt::SockType)? { match socket::getsockopt(fd.as_raw_fd(), socket::sockopt::SockType)? {
socket::SockType::Datagram => ( socket::SockType::Datagram => (
host::__WASI_FILETYPE_SOCKET_DGRAM, wasi::__WASI_FILETYPE_SOCKET_DGRAM,
host::RIGHTS_SOCKET_BASE, wasi::RIGHTS_SOCKET_BASE,
host::RIGHTS_SOCKET_INHERITING, wasi::RIGHTS_SOCKET_INHERITING,
), ),
socket::SockType::Stream => ( socket::SockType::Stream => (
host::__WASI_FILETYPE_SOCKET_STREAM, wasi::__WASI_FILETYPE_SOCKET_STREAM,
host::RIGHTS_SOCKET_BASE, wasi::RIGHTS_SOCKET_BASE,
host::RIGHTS_SOCKET_INHERITING, wasi::RIGHTS_SOCKET_INHERITING,
), ),
_ => return Err(Error::EINVAL), _ => return Err(Error::EINVAL),
} }
} else if ft.is_fifo() { } else if ft.is_fifo() {
log::debug!("Host fd {:?} is a fifo", fd.as_raw_fd()); log::debug!("Host fd {:?} is a fifo", fd.as_raw_fd());
( (
host::__WASI_FILETYPE_UNKNOWN, wasi::__WASI_FILETYPE_UNKNOWN,
host::RIGHTS_REGULAR_FILE_BASE, wasi::RIGHTS_REGULAR_FILE_BASE,
host::RIGHTS_REGULAR_FILE_INHERITING, wasi::RIGHTS_REGULAR_FILE_INHERITING,
) )
} else { } else {
log::debug!("Host fd {:?} is unknown", fd.as_raw_fd()); log::debug!("Host fd {:?} is unknown", fd.as_raw_fd());

View File

@@ -3,7 +3,7 @@
#![allow(non_snake_case)] #![allow(non_snake_case)]
#![allow(dead_code)] #![allow(dead_code)]
use crate::hostcalls_impl::FileType; use crate::hostcalls_impl::FileType;
use crate::{host, Error, Result}; use crate::{helpers, wasi, Error, Result};
use log::warn; use log::warn;
use std::ffi::OsStr; use std::ffi::OsStr;
use std::os::unix::prelude::OsStrExt; use std::os::unix::prelude::OsStrExt;
@@ -106,61 +106,61 @@ pub(crate) fn errno_from_nix(errno: nix::errno::Errno) -> Error {
} }
} }
pub(crate) fn nix_from_fdflags(fdflags: host::__wasi_fdflags_t) -> nix::fcntl::OFlag { pub(crate) fn nix_from_fdflags(fdflags: wasi::__wasi_fdflags_t) -> nix::fcntl::OFlag {
use nix::fcntl::OFlag; use nix::fcntl::OFlag;
let mut nix_flags = OFlag::empty(); let mut nix_flags = OFlag::empty();
if fdflags & host::__WASI_FDFLAG_APPEND != 0 { if fdflags & wasi::__WASI_FDFLAG_APPEND != 0 {
nix_flags.insert(OFlag::O_APPEND); nix_flags.insert(OFlag::O_APPEND);
} }
if fdflags & host::__WASI_FDFLAG_DSYNC != 0 { if fdflags & wasi::__WASI_FDFLAG_DSYNC != 0 {
nix_flags.insert(OFlag::O_DSYNC); nix_flags.insert(OFlag::O_DSYNC);
} }
if fdflags & host::__WASI_FDFLAG_NONBLOCK != 0 { if fdflags & wasi::__WASI_FDFLAG_NONBLOCK != 0 {
nix_flags.insert(OFlag::O_NONBLOCK); nix_flags.insert(OFlag::O_NONBLOCK);
} }
if fdflags & host::__WASI_FDFLAG_RSYNC != 0 { if fdflags & wasi::__WASI_FDFLAG_RSYNC != 0 {
nix_flags.insert(O_RSYNC); nix_flags.insert(O_RSYNC);
} }
if fdflags & host::__WASI_FDFLAG_SYNC != 0 { if fdflags & wasi::__WASI_FDFLAG_SYNC != 0 {
nix_flags.insert(OFlag::O_SYNC); nix_flags.insert(OFlag::O_SYNC);
} }
nix_flags nix_flags
} }
pub(crate) fn fdflags_from_nix(oflags: nix::fcntl::OFlag) -> host::__wasi_fdflags_t { pub(crate) fn fdflags_from_nix(oflags: nix::fcntl::OFlag) -> wasi::__wasi_fdflags_t {
use nix::fcntl::OFlag; use nix::fcntl::OFlag;
let mut fdflags = 0; let mut fdflags = 0;
if oflags.contains(OFlag::O_APPEND) { if oflags.contains(OFlag::O_APPEND) {
fdflags |= host::__WASI_FDFLAG_APPEND; fdflags |= wasi::__WASI_FDFLAG_APPEND;
} }
if oflags.contains(OFlag::O_DSYNC) { if oflags.contains(OFlag::O_DSYNC) {
fdflags |= host::__WASI_FDFLAG_DSYNC; fdflags |= wasi::__WASI_FDFLAG_DSYNC;
} }
if oflags.contains(OFlag::O_NONBLOCK) { if oflags.contains(OFlag::O_NONBLOCK) {
fdflags |= host::__WASI_FDFLAG_NONBLOCK; fdflags |= wasi::__WASI_FDFLAG_NONBLOCK;
} }
if oflags.contains(O_RSYNC) { if oflags.contains(O_RSYNC) {
fdflags |= host::__WASI_FDFLAG_RSYNC; fdflags |= wasi::__WASI_FDFLAG_RSYNC;
} }
if oflags.contains(OFlag::O_SYNC) { if oflags.contains(OFlag::O_SYNC) {
fdflags |= host::__WASI_FDFLAG_SYNC; fdflags |= wasi::__WASI_FDFLAG_SYNC;
} }
fdflags fdflags
} }
pub(crate) fn nix_from_oflags(oflags: host::__wasi_oflags_t) -> nix::fcntl::OFlag { pub(crate) fn nix_from_oflags(oflags: wasi::__wasi_oflags_t) -> nix::fcntl::OFlag {
use nix::fcntl::OFlag; use nix::fcntl::OFlag;
let mut nix_flags = OFlag::empty(); let mut nix_flags = OFlag::empty();
if oflags & host::__WASI_O_CREAT != 0 { if oflags & wasi::__WASI_O_CREAT != 0 {
nix_flags.insert(OFlag::O_CREAT); nix_flags.insert(OFlag::O_CREAT);
} }
if oflags & host::__WASI_O_DIRECTORY != 0 { if oflags & wasi::__WASI_O_DIRECTORY != 0 {
nix_flags.insert(OFlag::O_DIRECTORY); nix_flags.insert(OFlag::O_DIRECTORY);
} }
if oflags & host::__WASI_O_EXCL != 0 { if oflags & wasi::__WASI_O_EXCL != 0 {
nix_flags.insert(OFlag::O_EXCL); nix_flags.insert(OFlag::O_EXCL);
} }
if oflags & host::__WASI_O_TRUNC != 0 { if oflags & wasi::__WASI_O_TRUNC != 0 {
nix_flags.insert(OFlag::O_TRUNC); nix_flags.insert(OFlag::O_TRUNC);
} }
nix_flags nix_flags
@@ -187,26 +187,26 @@ pub(crate) fn filetype_from_nix(sflags: nix::sys::stat::SFlag) -> FileType {
pub(crate) fn filestat_from_nix( pub(crate) fn filestat_from_nix(
filestat: nix::sys::stat::FileStat, filestat: nix::sys::stat::FileStat,
) -> Result<host::__wasi_filestat_t> { ) -> Result<wasi::__wasi_filestat_t> {
use std::convert::TryFrom; use std::convert::TryFrom;
fn filestat_to_timestamp(secs: u64, nsecs: u64) -> Result<host::__wasi_timestamp_t> { fn filestat_to_timestamp(secs: u64, nsecs: u64) -> Result<wasi::__wasi_timestamp_t> {
secs.checked_mul(1_000_000_000) secs.checked_mul(1_000_000_000)
.and_then(|sec_nsec| sec_nsec.checked_add(nsecs)) .and_then(|sec_nsec| sec_nsec.checked_add(nsecs))
.ok_or(Error::EOVERFLOW) .ok_or(Error::EOVERFLOW)
} }
let filetype = nix::sys::stat::SFlag::from_bits_truncate(filestat.st_mode); let filetype = nix::sys::stat::SFlag::from_bits_truncate(filestat.st_mode);
let dev = host::__wasi_device_t::try_from(filestat.st_dev)?; let dev = wasi::__wasi_device_t::try_from(filestat.st_dev)?;
let ino = host::__wasi_inode_t::try_from(filestat.st_ino)?; let ino = wasi::__wasi_inode_t::try_from(filestat.st_ino)?;
let st_atim = filestat_to_timestamp(filestat.st_atime as u64, filestat.st_atime_nsec as u64)?; let st_atim = filestat_to_timestamp(filestat.st_atime as u64, filestat.st_atime_nsec as u64)?;
let st_ctim = filestat_to_timestamp(filestat.st_ctime as u64, filestat.st_ctime_nsec as u64)?; let st_ctim = filestat_to_timestamp(filestat.st_ctime as u64, filestat.st_ctime_nsec as u64)?;
let st_mtim = filestat_to_timestamp(filestat.st_mtime as u64, filestat.st_mtime_nsec as u64)?; let st_mtim = filestat_to_timestamp(filestat.st_mtime as u64, filestat.st_mtime_nsec as u64)?;
Ok(host::__wasi_filestat_t { Ok(wasi::__wasi_filestat_t {
st_dev: dev, st_dev: dev,
st_ino: ino, st_ino: ino,
st_nlink: filestat.st_nlink as host::__wasi_linkcount_t, st_nlink: filestat.st_nlink as wasi::__wasi_linkcount_t,
st_size: filestat.st_size as host::__wasi_filesize_t, st_size: filestat.st_size as wasi::__wasi_filesize_t,
st_atim, st_atim,
st_ctim, st_ctim,
st_mtim, st_mtim,
@@ -216,23 +216,23 @@ pub(crate) fn filestat_from_nix(
pub(crate) fn dirent_filetype_from_host( pub(crate) fn dirent_filetype_from_host(
host_entry: &nix::libc::dirent, host_entry: &nix::libc::dirent,
) -> Result<host::__wasi_filetype_t> { ) -> Result<wasi::__wasi_filetype_t> {
match host_entry.d_type { match host_entry.d_type {
libc::DT_FIFO => Ok(host::__WASI_FILETYPE_UNKNOWN), libc::DT_FIFO => Ok(wasi::__WASI_FILETYPE_UNKNOWN),
libc::DT_CHR => Ok(host::__WASI_FILETYPE_CHARACTER_DEVICE), libc::DT_CHR => Ok(wasi::__WASI_FILETYPE_CHARACTER_DEVICE),
libc::DT_DIR => Ok(host::__WASI_FILETYPE_DIRECTORY), libc::DT_DIR => Ok(wasi::__WASI_FILETYPE_DIRECTORY),
libc::DT_BLK => Ok(host::__WASI_FILETYPE_BLOCK_DEVICE), libc::DT_BLK => Ok(wasi::__WASI_FILETYPE_BLOCK_DEVICE),
libc::DT_REG => Ok(host::__WASI_FILETYPE_REGULAR_FILE), libc::DT_REG => Ok(wasi::__WASI_FILETYPE_REGULAR_FILE),
libc::DT_LNK => Ok(host::__WASI_FILETYPE_SYMBOLIC_LINK), libc::DT_LNK => Ok(wasi::__WASI_FILETYPE_SYMBOLIC_LINK),
libc::DT_SOCK => { libc::DT_SOCK => {
// TODO how to discriminate between STREAM and DGRAM? // TODO how to discriminate between STREAM and DGRAM?
// Perhaps, we should create a more general WASI filetype // Perhaps, we should create a more general WASI filetype
// such as __WASI_FILETYPE_SOCKET, and then it would be // such as __WASI_FILETYPE_SOCKET, and then it would be
// up to the client to check whether it's actually // up to the client to check whether it's actually
// STREAM or DGRAM? // STREAM or DGRAM?
Ok(host::__WASI_FILETYPE_UNKNOWN) Ok(wasi::__WASI_FILETYPE_UNKNOWN)
} }
libc::DT_UNKNOWN => Ok(host::__WASI_FILETYPE_UNKNOWN), libc::DT_UNKNOWN => Ok(wasi::__WASI_FILETYPE_UNKNOWN),
_ => Err(Error::EINVAL), _ => Err(Error::EINVAL),
} }
} }
@@ -242,5 +242,5 @@ pub(crate) fn dirent_filetype_from_host(
/// NB WASI spec requires OS string to be valid UTF-8. Otherwise, /// NB WASI spec requires OS string to be valid UTF-8. Otherwise,
/// `__WASI_EILSEQ` error is returned. /// `__WASI_EILSEQ` error is returned.
pub(crate) fn path_from_host<S: AsRef<OsStr>>(s: S) -> Result<String> { pub(crate) fn path_from_host<S: AsRef<OsStr>>(s: S) -> Result<String> {
host::path_from_slice(s.as_ref().as_bytes()).map(String::from) helpers::path_from_slice(s.as_ref().as_bytes()).map(String::from)
} }

View File

@@ -5,7 +5,7 @@ use crate::helpers::systemtime_to_timestamp;
use crate::hostcalls_impl::{FileType, PathGet}; use crate::hostcalls_impl::{FileType, PathGet};
use crate::sys::host_impl; use crate::sys::host_impl;
use crate::sys::unix::str_to_cstring; use crate::sys::unix::str_to_cstring;
use crate::{host, Error, Result}; use crate::{wasi, Error, Result};
use nix::libc; use nix::libc;
use std::convert::TryInto; use std::convert::TryInto;
use std::fs::{File, Metadata}; use std::fs::{File, Metadata};
@@ -30,16 +30,16 @@ cfg_if::cfg_if! {
pub(crate) fn fd_pread( pub(crate) fn fd_pread(
file: &File, file: &File,
buf: &mut [u8], buf: &mut [u8],
offset: host::__wasi_filesize_t, offset: wasi::__wasi_filesize_t,
) -> Result<usize> { ) -> Result<usize> {
file.read_at(buf, offset).map_err(Into::into) file.read_at(buf, offset).map_err(Into::into)
} }
pub(crate) fn fd_pwrite(file: &File, buf: &[u8], offset: host::__wasi_filesize_t) -> Result<usize> { pub(crate) fn fd_pwrite(file: &File, buf: &[u8], offset: wasi::__wasi_filesize_t) -> Result<usize> {
file.write_at(buf, offset).map_err(Into::into) file.write_at(buf, offset).map_err(Into::into)
} }
pub(crate) fn fd_fdstat_get(fd: &File) -> Result<host::__wasi_fdflags_t> { pub(crate) fn fd_fdstat_get(fd: &File) -> Result<wasi::__wasi_fdflags_t> {
use nix::fcntl::{fcntl, OFlag, F_GETFL}; use nix::fcntl::{fcntl, OFlag, F_GETFL};
match fcntl(fd.as_raw_fd(), F_GETFL).map(OFlag::from_bits_truncate) { match fcntl(fd.as_raw_fd(), F_GETFL).map(OFlag::from_bits_truncate) {
Ok(flags) => Ok(host_impl::fdflags_from_nix(flags)), Ok(flags) => Ok(host_impl::fdflags_from_nix(flags)),
@@ -47,7 +47,7 @@ pub(crate) fn fd_fdstat_get(fd: &File) -> Result<host::__wasi_fdflags_t> {
} }
} }
pub(crate) fn fd_fdstat_set_flags(fd: &File, fdflags: host::__wasi_fdflags_t) -> Result<()> { pub(crate) fn fd_fdstat_set_flags(fd: &File, fdflags: wasi::__wasi_fdflags_t) -> Result<()> {
use nix::fcntl::{fcntl, F_SETFL}; use nix::fcntl::{fcntl, F_SETFL};
let nix_flags = host_impl::nix_from_fdflags(fdflags); let nix_flags = host_impl::nix_from_fdflags(fdflags);
match fcntl(fd.as_raw_fd(), F_SETFL(nix_flags)) { match fcntl(fd.as_raw_fd(), F_SETFL(nix_flags)) {
@@ -93,8 +93,8 @@ pub(crate) fn path_open(
resolved: PathGet, resolved: PathGet,
read: bool, read: bool,
write: bool, write: bool,
oflags: host::__wasi_oflags_t, oflags: wasi::__wasi_oflags_t,
fs_flags: host::__wasi_fdflags_t, fs_flags: wasi::__wasi_fdflags_t,
) -> Result<File> { ) -> Result<File> {
use nix::errno::Errno; use nix::errno::Errno;
use nix::fcntl::{openat, AtFlags, OFlag}; use nix::fcntl::{openat, AtFlags, OFlag};
@@ -213,11 +213,11 @@ pub(crate) fn path_readlink(resolved: PathGet, buf: &mut [u8]) -> Result<usize>
} }
} }
pub(crate) fn fd_filestat_get_impl(file: &std::fs::File) -> Result<host::__wasi_filestat_t> { pub(crate) fn fd_filestat_get_impl(file: &std::fs::File) -> Result<wasi::__wasi_filestat_t> {
use std::os::unix::fs::MetadataExt; use std::os::unix::fs::MetadataExt;
let metadata = file.metadata()?; let metadata = file.metadata()?;
Ok(host::__wasi_filestat_t { Ok(wasi::__wasi_filestat_t {
st_dev: metadata.dev(), st_dev: metadata.dev(),
st_ino: metadata.ino(), st_ino: metadata.ino(),
st_nlink: metadata.nlink().try_into()?, // u64 doesn't fit into u32 st_nlink: metadata.nlink().try_into()?, // u64 doesn't fit into u32
@@ -259,8 +259,8 @@ fn filetype(file: &File, metadata: &Metadata) -> Result<FileType> {
pub(crate) fn path_filestat_get( pub(crate) fn path_filestat_get(
resolved: PathGet, resolved: PathGet,
dirflags: host::__wasi_lookupflags_t, dirflags: wasi::__wasi_lookupflags_t,
) -> Result<host::__wasi_filestat_t> { ) -> Result<wasi::__wasi_filestat_t> {
use nix::fcntl::AtFlags; use nix::fcntl::AtFlags;
use nix::sys::stat::fstatat; use nix::sys::stat::fstatat;
@@ -276,10 +276,10 @@ pub(crate) fn path_filestat_get(
pub(crate) fn path_filestat_set_times( pub(crate) fn path_filestat_set_times(
resolved: PathGet, resolved: PathGet,
dirflags: host::__wasi_lookupflags_t, dirflags: wasi::__wasi_lookupflags_t,
st_atim: host::__wasi_timestamp_t, st_atim: wasi::__wasi_timestamp_t,
st_mtim: host::__wasi_timestamp_t, st_mtim: wasi::__wasi_timestamp_t,
fst_flags: host::__wasi_fstflags_t, fst_flags: wasi::__wasi_fstflags_t,
) -> Result<()> { ) -> Result<()> {
use nix::sys::stat::{utimensat, UtimensatFlags}; use nix::sys::stat::{utimensat, UtimensatFlags};
use nix::sys::time::{TimeSpec, TimeValLike}; use nix::sys::time::{TimeSpec, TimeValLike};
@@ -301,17 +301,17 @@ pub(crate) fn path_filestat_set_times(
unsafe { std::mem::transmute(raw_ts) } unsafe { std::mem::transmute(raw_ts) }
}; };
let set_atim = fst_flags & host::__WASI_FILESTAT_SET_ATIM != 0; let set_atim = fst_flags & wasi::__WASI_FILESTAT_SET_ATIM != 0;
let set_atim_now = fst_flags & host::__WASI_FILESTAT_SET_ATIM_NOW != 0; let set_atim_now = fst_flags & wasi::__WASI_FILESTAT_SET_ATIM_NOW != 0;
let set_mtim = fst_flags & host::__WASI_FILESTAT_SET_MTIM != 0; let set_mtim = fst_flags & wasi::__WASI_FILESTAT_SET_MTIM != 0;
let set_mtim_now = fst_flags & host::__WASI_FILESTAT_SET_MTIM_NOW != 0; let set_mtim_now = fst_flags & wasi::__WASI_FILESTAT_SET_MTIM_NOW != 0;
if (set_atim && set_atim_now) || (set_mtim && set_mtim_now) { if (set_atim && set_atim_now) || (set_mtim && set_mtim_now) {
return Err(Error::EINVAL); return Err(Error::EINVAL);
} }
let atflags = match dirflags { let atflags = match dirflags {
host::__WASI_LOOKUP_SYMLINK_FOLLOW => UtimensatFlags::FollowSymlink, wasi::__WASI_LOOKUP_SYMLINK_FOLLOW => UtimensatFlags::FollowSymlink,
_ => UtimensatFlags::NoFollowSymlink, _ => UtimensatFlags::NoFollowSymlink,
}; };

View File

@@ -1,7 +1,7 @@
#![allow(non_camel_case_types)] #![allow(non_camel_case_types)]
#![allow(unused_unsafe)] #![allow(unused_unsafe)]
use crate::sys::host_impl; use crate::sys::host_impl;
use crate::{host, Result}; use crate::{wasi, Result};
use std::fs::File; use std::fs::File;
cfg_if::cfg_if! { cfg_if::cfg_if! {
@@ -20,33 +20,33 @@ cfg_if::cfg_if! {
} }
pub(crate) fn path_open_rights( pub(crate) fn path_open_rights(
rights_base: host::__wasi_rights_t, rights_base: wasi::__wasi_rights_t,
rights_inheriting: host::__wasi_rights_t, rights_inheriting: wasi::__wasi_rights_t,
oflags: host::__wasi_oflags_t, oflags: wasi::__wasi_oflags_t,
fs_flags: host::__wasi_fdflags_t, fs_flags: wasi::__wasi_fdflags_t,
) -> (host::__wasi_rights_t, host::__wasi_rights_t) { ) -> (wasi::__wasi_rights_t, wasi::__wasi_rights_t) {
use nix::fcntl::OFlag; use nix::fcntl::OFlag;
// which rights are needed on the dirfd? // which rights are needed on the dirfd?
let mut needed_base = host::__WASI_RIGHT_PATH_OPEN; let mut needed_base = wasi::__WASI_RIGHT_PATH_OPEN;
let mut needed_inheriting = rights_base | rights_inheriting; let mut needed_inheriting = rights_base | rights_inheriting;
// convert open flags // convert open flags
let oflags = host_impl::nix_from_oflags(oflags); let oflags = host_impl::nix_from_oflags(oflags);
if oflags.contains(OFlag::O_CREAT) { if oflags.contains(OFlag::O_CREAT) {
needed_base |= host::__WASI_RIGHT_PATH_CREATE_FILE; needed_base |= wasi::__WASI_RIGHT_PATH_CREATE_FILE;
} }
if oflags.contains(OFlag::O_TRUNC) { if oflags.contains(OFlag::O_TRUNC) {
needed_base |= host::__WASI_RIGHT_PATH_FILESTAT_SET_SIZE; needed_base |= wasi::__WASI_RIGHT_PATH_FILESTAT_SET_SIZE;
} }
// convert file descriptor flags // convert file descriptor flags
let fdflags = host_impl::nix_from_fdflags(fs_flags); let fdflags = host_impl::nix_from_fdflags(fs_flags);
if fdflags.contains(OFlag::O_DSYNC) { if fdflags.contains(OFlag::O_DSYNC) {
needed_inheriting |= host::__WASI_RIGHT_FD_DATASYNC; needed_inheriting |= wasi::__WASI_RIGHT_FD_DATASYNC;
} }
if fdflags.intersects(host_impl::O_RSYNC | OFlag::O_SYNC) { if fdflags.intersects(host_impl::O_RSYNC | OFlag::O_SYNC) {
needed_inheriting |= host::__WASI_RIGHT_FD_SYNC; needed_inheriting |= wasi::__WASI_RIGHT_FD_SYNC;
} }
(needed_base, needed_inheriting) (needed_base, needed_inheriting)

View File

@@ -2,17 +2,17 @@
#![allow(unused_unsafe)] #![allow(unused_unsafe)]
use crate::hostcalls_impl::{ClockEventData, FdEventData}; use crate::hostcalls_impl::{ClockEventData, FdEventData};
use crate::sys::host_impl; use crate::sys::host_impl;
use crate::{host, Error, Result}; use crate::{wasi, Error, Result};
use nix::libc::{self, c_int}; use nix::libc::{self, c_int};
use std::mem::MaybeUninit; use std::mem::MaybeUninit;
pub(crate) fn clock_res_get(clock_id: host::__wasi_clockid_t) -> Result<host::__wasi_timestamp_t> { pub(crate) fn clock_res_get(clock_id: wasi::__wasi_clockid_t) -> Result<wasi::__wasi_timestamp_t> {
// convert the supported clocks to the libc types, or return EINVAL // convert the supported clocks to the libc types, or return EINVAL
let clock_id = match clock_id { let clock_id = match clock_id {
host::__WASI_CLOCK_REALTIME => libc::CLOCK_REALTIME, wasi::__WASI_CLOCK_REALTIME => libc::CLOCK_REALTIME,
host::__WASI_CLOCK_MONOTONIC => libc::CLOCK_MONOTONIC, wasi::__WASI_CLOCK_MONOTONIC => libc::CLOCK_MONOTONIC,
host::__WASI_CLOCK_PROCESS_CPUTIME_ID => libc::CLOCK_PROCESS_CPUTIME_ID, wasi::__WASI_CLOCK_PROCESS_CPUTIME_ID => libc::CLOCK_PROCESS_CPUTIME_ID,
host::__WASI_CLOCK_THREAD_CPUTIME_ID => libc::CLOCK_THREAD_CPUTIME_ID, wasi::__WASI_CLOCK_THREAD_CPUTIME_ID => libc::CLOCK_THREAD_CPUTIME_ID,
_ => return Err(Error::EINVAL), _ => return Err(Error::EINVAL),
}; };
@@ -27,9 +27,9 @@ pub(crate) fn clock_res_get(clock_id: host::__wasi_clockid_t) -> Result<host::__
// convert to nanoseconds, returning EOVERFLOW in case of overflow; // convert to nanoseconds, returning EOVERFLOW in case of overflow;
// this is freelancing a bit from the spec but seems like it'll // this is freelancing a bit from the spec but seems like it'll
// be an unusual situation to hit // be an unusual situation to hit
(timespec.tv_sec as host::__wasi_timestamp_t) (timespec.tv_sec as wasi::__wasi_timestamp_t)
.checked_mul(1_000_000_000) .checked_mul(1_000_000_000)
.and_then(|sec_ns| sec_ns.checked_add(timespec.tv_nsec as host::__wasi_timestamp_t)) .and_then(|sec_ns| sec_ns.checked_add(timespec.tv_nsec as wasi::__wasi_timestamp_t))
.map_or(Err(Error::EOVERFLOW), |resolution| { .map_or(Err(Error::EOVERFLOW), |resolution| {
// a supported clock can never return zero; this case will probably never get hit, but // a supported clock can never return zero; this case will probably never get hit, but
// make sure we follow the spec // make sure we follow the spec
@@ -41,13 +41,13 @@ pub(crate) fn clock_res_get(clock_id: host::__wasi_clockid_t) -> Result<host::__
}) })
} }
pub(crate) fn clock_time_get(clock_id: host::__wasi_clockid_t) -> Result<host::__wasi_timestamp_t> { pub(crate) fn clock_time_get(clock_id: wasi::__wasi_clockid_t) -> Result<wasi::__wasi_timestamp_t> {
// convert the supported clocks to the libc types, or return EINVAL // convert the supported clocks to the libc types, or return EINVAL
let clock_id = match clock_id { let clock_id = match clock_id {
host::__WASI_CLOCK_REALTIME => libc::CLOCK_REALTIME, wasi::__WASI_CLOCK_REALTIME => libc::CLOCK_REALTIME,
host::__WASI_CLOCK_MONOTONIC => libc::CLOCK_MONOTONIC, wasi::__WASI_CLOCK_MONOTONIC => libc::CLOCK_MONOTONIC,
host::__WASI_CLOCK_PROCESS_CPUTIME_ID => libc::CLOCK_PROCESS_CPUTIME_ID, wasi::__WASI_CLOCK_PROCESS_CPUTIME_ID => libc::CLOCK_PROCESS_CPUTIME_ID,
host::__WASI_CLOCK_THREAD_CPUTIME_ID => libc::CLOCK_THREAD_CPUTIME_ID, wasi::__WASI_CLOCK_THREAD_CPUTIME_ID => libc::CLOCK_THREAD_CPUTIME_ID,
_ => return Err(Error::EINVAL), _ => return Err(Error::EINVAL),
}; };
@@ -61,16 +61,17 @@ pub(crate) fn clock_time_get(clock_id: host::__wasi_clockid_t) -> Result<host::_
// convert to nanoseconds, returning EOVERFLOW in case of overflow; this is freelancing a bit // convert to nanoseconds, returning EOVERFLOW in case of overflow; this is freelancing a bit
// from the spec but seems like it'll be an unusual situation to hit // from the spec but seems like it'll be an unusual situation to hit
(timespec.tv_sec as host::__wasi_timestamp_t) (timespec.tv_sec as wasi::__wasi_timestamp_t)
.checked_mul(1_000_000_000) .checked_mul(1_000_000_000)
.and_then(|sec_ns| sec_ns.checked_add(timespec.tv_nsec as host::__wasi_timestamp_t)) .and_then(|sec_ns| sec_ns.checked_add(timespec.tv_nsec as wasi::__wasi_timestamp_t))
.map_or(Err(Error::EOVERFLOW), Ok) .map_or(Err(Error::EOVERFLOW), Ok)
} }
pub(crate) fn poll_oneoff( pub(crate) fn poll_oneoff(
timeout: Option<ClockEventData>, timeout: Option<ClockEventData>,
fd_events: Vec<FdEventData>, fd_events: Vec<FdEventData>,
) -> Result<Vec<host::__wasi_event_t>> { events: &mut Vec<wasi::__wasi_event_t>,
) -> Result<()> {
use nix::{ use nix::{
errno::Errno, errno::Errno,
poll::{poll, PollFd, PollFlags}, poll::{poll, PollFd, PollFlags},
@@ -78,7 +79,7 @@ pub(crate) fn poll_oneoff(
use std::{convert::TryInto, os::unix::prelude::AsRawFd}; use std::{convert::TryInto, os::unix::prelude::AsRawFd};
if fd_events.is_empty() && timeout.is_none() { if fd_events.is_empty() && timeout.is_none() {
return Ok(vec![]); return Ok(());
} }
let mut poll_fds: Vec<_> = fd_events let mut poll_fds: Vec<_> = fd_events
@@ -86,8 +87,8 @@ pub(crate) fn poll_oneoff(
.map(|event| { .map(|event| {
let mut flags = PollFlags::empty(); let mut flags = PollFlags::empty();
match event.type_ { match event.type_ {
host::__WASI_EVENTTYPE_FD_READ => flags.insert(PollFlags::POLLIN), wasi::__WASI_EVENTTYPE_FD_READ => flags.insert(PollFlags::POLLIN),
host::__WASI_EVENTTYPE_FD_WRITE => flags.insert(PollFlags::POLLOUT), wasi::__WASI_EVENTTYPE_FD_WRITE => flags.insert(PollFlags::POLLOUT),
// An event on a file descriptor can currently only be of type FD_READ or FD_WRITE // An event on a file descriptor can currently only be of type FD_READ or FD_WRITE
// Nothing else has been defined in the specification, and these are also the only two // Nothing else has been defined in the specification, and these are also the only two
// events we filtered before. If we get something else here, the code has a serious bug. // events we filtered before. If we get something else here, the code has a serious bug.
@@ -116,38 +117,43 @@ pub(crate) fn poll_oneoff(
}; };
Ok(if ready == 0 { Ok(if ready == 0 {
poll_oneoff_handle_timeout_event(timeout.expect("timeout should not be None")) poll_oneoff_handle_timeout_event(timeout.expect("timeout should not be None"), events)
} else { } else {
let events = fd_events.into_iter().zip(poll_fds.into_iter()).take(ready); let ready_events = fd_events.into_iter().zip(poll_fds.into_iter()).take(ready);
poll_oneoff_handle_fd_event(events)? poll_oneoff_handle_fd_event(ready_events, events)?
}) })
} }
// define the `fionread()` function, equivalent to `ioctl(fd, FIONREAD, *bytes)` // define the `fionread()` function, equivalent to `ioctl(fd, FIONREAD, *bytes)`
nix::ioctl_read_bad!(fionread, nix::libc::FIONREAD, c_int); nix::ioctl_read_bad!(fionread, nix::libc::FIONREAD, c_int);
fn poll_oneoff_handle_timeout_event(timeout: ClockEventData) -> Vec<host::__wasi_event_t> { fn poll_oneoff_handle_timeout_event(
vec![host::__wasi_event_t { timeout: ClockEventData,
events: &mut Vec<wasi::__wasi_event_t>,
) {
events.push(wasi::__wasi_event_t {
userdata: timeout.userdata, userdata: timeout.userdata,
type_: host::__WASI_EVENTTYPE_CLOCK, type_: wasi::__WASI_EVENTTYPE_CLOCK,
error: host::__WASI_ESUCCESS, error: wasi::__WASI_ESUCCESS,
u: host::__wasi_event_t___wasi_event_u { u: wasi::__wasi_event_t___wasi_event_u {
fd_readwrite: host::__wasi_event_t___wasi_event_u___wasi_event_u_fd_readwrite_t { fd_readwrite: wasi::__wasi_event_t___wasi_event_u___wasi_event_u_fd_readwrite_t {
nbytes: 0, nbytes: 0,
flags: 0, flags: 0,
__bindgen_padding_0: [0, 0, 0],
}, },
}, },
}] __bindgen_padding_0: 0,
});
} }
fn poll_oneoff_handle_fd_event<'a>( fn poll_oneoff_handle_fd_event<'a>(
events: impl Iterator<Item = (FdEventData<'a>, nix::poll::PollFd)>, ready_events: impl Iterator<Item = (FdEventData<'a>, nix::poll::PollFd)>,
) -> Result<Vec<host::__wasi_event_t>> { events: &mut Vec<wasi::__wasi_event_t>,
) -> Result<()> {
use nix::poll::PollFlags; use nix::poll::PollFlags;
use std::{convert::TryInto, os::unix::prelude::AsRawFd}; use std::{convert::TryInto, os::unix::prelude::AsRawFd};
let mut output_events = Vec::new(); for (fd_event, poll_fd) in ready_events {
for (fd_event, poll_fd) in events {
log::debug!("poll_oneoff_handle_fd_event fd_event = {:?}", fd_event); log::debug!("poll_oneoff_handle_fd_event fd_event = {:?}", fd_event);
log::debug!("poll_oneoff_handle_fd_event poll_fd = {:?}", poll_fd); log::debug!("poll_oneoff_handle_fd_event poll_fd = {:?}", poll_fd);
@@ -159,68 +165,76 @@ fn poll_oneoff_handle_fd_event<'a>(
log::debug!("poll_oneoff_handle_fd_event revents = {:?}", revents); log::debug!("poll_oneoff_handle_fd_event revents = {:?}", revents);
let mut nbytes = 0; let mut nbytes = 0;
if fd_event.type_ == host::__WASI_EVENTTYPE_FD_READ { if fd_event.type_ == wasi::__WASI_EVENTTYPE_FD_READ {
let _ = unsafe { fionread(fd_event.descriptor.as_raw_fd(), &mut nbytes) }; let _ = unsafe { fionread(fd_event.descriptor.as_raw_fd(), &mut nbytes) };
} }
let output_event = if revents.contains(PollFlags::POLLNVAL) { let output_event = if revents.contains(PollFlags::POLLNVAL) {
host::__wasi_event_t { wasi::__wasi_event_t {
userdata: fd_event.userdata, userdata: fd_event.userdata,
type_: fd_event.type_, type_: fd_event.type_,
error: host::__WASI_EBADF, error: wasi::__WASI_EBADF,
u: host::__wasi_event_t___wasi_event_u { u: wasi::__wasi_event_t___wasi_event_u {
fd_readwrite: fd_readwrite:
host::__wasi_event_t___wasi_event_u___wasi_event_u_fd_readwrite_t { wasi::__wasi_event_t___wasi_event_u___wasi_event_u_fd_readwrite_t {
nbytes: 0, nbytes: 0,
flags: host::__WASI_EVENT_FD_READWRITE_HANGUP, flags: wasi::__WASI_EVENT_FD_READWRITE_HANGUP,
__bindgen_padding_0: [0, 0, 0],
}, },
}, },
__bindgen_padding_0: 0,
} }
} else if revents.contains(PollFlags::POLLERR) { } else if revents.contains(PollFlags::POLLERR) {
host::__wasi_event_t { wasi::__wasi_event_t {
userdata: fd_event.userdata, userdata: fd_event.userdata,
type_: fd_event.type_, type_: fd_event.type_,
error: host::__WASI_EIO, error: wasi::__WASI_EIO,
u: host::__wasi_event_t___wasi_event_u { u: wasi::__wasi_event_t___wasi_event_u {
fd_readwrite: fd_readwrite:
host::__wasi_event_t___wasi_event_u___wasi_event_u_fd_readwrite_t { wasi::__wasi_event_t___wasi_event_u___wasi_event_u_fd_readwrite_t {
nbytes: 0, nbytes: 0,
flags: host::__WASI_EVENT_FD_READWRITE_HANGUP, flags: wasi::__WASI_EVENT_FD_READWRITE_HANGUP,
__bindgen_padding_0: [0, 0, 0],
}, },
}, },
__bindgen_padding_0: 0,
} }
} else if revents.contains(PollFlags::POLLHUP) { } else if revents.contains(PollFlags::POLLHUP) {
host::__wasi_event_t { wasi::__wasi_event_t {
userdata: fd_event.userdata, userdata: fd_event.userdata,
type_: fd_event.type_, type_: fd_event.type_,
error: host::__WASI_ESUCCESS, error: wasi::__WASI_ESUCCESS,
u: host::__wasi_event_t___wasi_event_u { u: wasi::__wasi_event_t___wasi_event_u {
fd_readwrite: fd_readwrite:
host::__wasi_event_t___wasi_event_u___wasi_event_u_fd_readwrite_t { wasi::__wasi_event_t___wasi_event_u___wasi_event_u_fd_readwrite_t {
nbytes: 0, nbytes: 0,
flags: host::__WASI_EVENT_FD_READWRITE_HANGUP, flags: wasi::__WASI_EVENT_FD_READWRITE_HANGUP,
__bindgen_padding_0: [0, 0, 0],
}, },
}, },
__bindgen_padding_0: 0,
} }
} else if revents.contains(PollFlags::POLLIN) | revents.contains(PollFlags::POLLOUT) { } else if revents.contains(PollFlags::POLLIN) | revents.contains(PollFlags::POLLOUT) {
host::__wasi_event_t { wasi::__wasi_event_t {
userdata: fd_event.userdata, userdata: fd_event.userdata,
type_: fd_event.type_, type_: fd_event.type_,
error: host::__WASI_ESUCCESS, error: wasi::__WASI_ESUCCESS,
u: host::__wasi_event_t___wasi_event_u { u: wasi::__wasi_event_t___wasi_event_u {
fd_readwrite: fd_readwrite:
host::__wasi_event_t___wasi_event_u___wasi_event_u_fd_readwrite_t { wasi::__wasi_event_t___wasi_event_u___wasi_event_u_fd_readwrite_t {
nbytes: nbytes.try_into()?, nbytes: nbytes.try_into()?,
flags: 0, flags: 0,
__bindgen_padding_0: [0, 0, 0],
}, },
}, },
__bindgen_padding_0: 0,
} }
} else { } else {
continue; continue;
}; };
output_events.push(output_event); events.push(output_event);
} }
Ok(output_events) Ok(())
} }

View File

@@ -2,7 +2,7 @@ use super::osfile::OsFile;
use crate::hostcalls_impl::PathGet; use crate::hostcalls_impl::PathGet;
use crate::sys::host_impl; use crate::sys::host_impl;
use crate::sys::unix::str_to_cstring; use crate::sys::unix::str_to_cstring;
use crate::{host, Error, Result}; use crate::{wasi, Error, Result};
use nix::libc::{self, c_long, c_void}; use nix::libc::{self, c_long, c_void};
use std::convert::TryInto; use std::convert::TryInto;
use std::fs::File; use std::fs::File;
@@ -70,7 +70,7 @@ pub(crate) fn path_rename(resolved_old: PathGet, resolved_new: PathGet) -> Resul
pub(crate) fn fd_readdir( pub(crate) fn fd_readdir(
os_file: &mut OsFile, os_file: &mut OsFile,
host_buf: &mut [u8], host_buf: &mut [u8],
cookie: host::__wasi_dircookie_t, cookie: wasi::__wasi_dircookie_t,
) -> Result<usize> { ) -> Result<usize> {
use libc::{dirent, fdopendir, readdir_r, rewinddir, seekdir}; use libc::{dirent, fdopendir, readdir_r, rewinddir, seekdir};
@@ -81,7 +81,7 @@ pub(crate) fn fd_readdir(
return Err(host_impl::errno_from_nix(nix::errno::Errno::last())); return Err(host_impl::errno_from_nix(nix::errno::Errno::last()));
} }
if cookie != host::__WASI_DIRCOOKIE_START { if cookie != wasi::__WASI_DIRCOOKIE_START {
unsafe { seekdir(dir, cookie as c_long) }; unsafe { seekdir(dir, cookie as c_long) };
} else { } else {
// If cookie set to __WASI_DIRCOOKIE_START, rewind the dir ptr // If cookie set to __WASI_DIRCOOKIE_START, rewind the dir ptr
@@ -108,7 +108,7 @@ pub(crate) fn fd_readdir(
break; break;
} }
unsafe { entry_buf.assume_init() }; unsafe { entry_buf.assume_init() };
let entry: host::__wasi_dirent_t = host_impl::dirent_from_host(&unsafe { *host_entry })?; let entry: wasi::__wasi_dirent_t = host_impl::dirent_from_host(&unsafe { *host_entry })?;
log::debug!("fd_readdir entry = {:?}", entry); log::debug!("fd_readdir entry = {:?}", entry);
@@ -119,7 +119,7 @@ pub(crate) fn fd_readdir(
} }
unsafe { unsafe {
let ptr = host_buf_ptr.offset(host_buf_offset.try_into()?) as *mut c_void let ptr = host_buf_ptr.offset(host_buf_offset.try_into()?) as *mut c_void
as *mut host::__wasi_dirent_t; as *mut wasi::__wasi_dirent_t;
*ptr = entry; *ptr = entry;
} }
host_buf_offset += std::mem::size_of_val(&entry); host_buf_offset += std::mem::size_of_val(&entry);
@@ -140,9 +140,9 @@ pub(crate) fn fd_readdir(
pub(crate) fn fd_advise( pub(crate) fn fd_advise(
file: &File, file: &File,
advice: host::__wasi_advice_t, advice: wasi::__wasi_advice_t,
offset: host::__wasi_filesize_t, offset: wasi::__wasi_filesize_t,
len: host::__wasi_filesize_t, len: wasi::__wasi_filesize_t,
) -> Result<()> { ) -> Result<()> {
{ {
use nix::fcntl::{posix_fadvise, PosixFadviseAdvice}; use nix::fcntl::{posix_fadvise, PosixFadviseAdvice};
@@ -150,12 +150,12 @@ pub(crate) fn fd_advise(
let offset = offset.try_into()?; let offset = offset.try_into()?;
let len = len.try_into()?; let len = len.try_into()?;
let host_advice = match advice { let host_advice = match advice {
host::__WASI_ADVICE_DONTNEED => PosixFadviseAdvice::POSIX_FADV_DONTNEED, wasi::__WASI_ADVICE_DONTNEED => PosixFadviseAdvice::POSIX_FADV_DONTNEED,
host::__WASI_ADVICE_SEQUENTIAL => PosixFadviseAdvice::POSIX_FADV_SEQUENTIAL, wasi::__WASI_ADVICE_SEQUENTIAL => PosixFadviseAdvice::POSIX_FADV_SEQUENTIAL,
host::__WASI_ADVICE_WILLNEED => PosixFadviseAdvice::POSIX_FADV_WILLNEED, wasi::__WASI_ADVICE_WILLNEED => PosixFadviseAdvice::POSIX_FADV_WILLNEED,
host::__WASI_ADVICE_NOREUSE => PosixFadviseAdvice::POSIX_FADV_NOREUSE, wasi::__WASI_ADVICE_NOREUSE => PosixFadviseAdvice::POSIX_FADV_NOREUSE,
host::__WASI_ADVICE_RANDOM => PosixFadviseAdvice::POSIX_FADV_RANDOM, wasi::__WASI_ADVICE_RANDOM => PosixFadviseAdvice::POSIX_FADV_RANDOM,
host::__WASI_ADVICE_NORMAL => PosixFadviseAdvice::POSIX_FADV_NORMAL, wasi::__WASI_ADVICE_NORMAL => PosixFadviseAdvice::POSIX_FADV_NORMAL,
_ => return Err(Error::EINVAL), _ => return Err(Error::EINVAL),
}; };

View File

@@ -27,14 +27,14 @@ pub(crate) mod fdentry_impl {
pub(crate) mod host_impl { pub(crate) mod host_impl {
use super::super::host_impl::dirent_filetype_from_host; use super::super::host_impl::dirent_filetype_from_host;
use crate::{host, memory, Error, Result}; use crate::{wasi, Error, Result};
pub(crate) const O_RSYNC: nix::fcntl::OFlag = nix::fcntl::OFlag::O_RSYNC; pub(crate) const O_RSYNC: nix::fcntl::OFlag = nix::fcntl::OFlag::O_RSYNC;
pub(crate) fn dirent_from_host( pub(crate) fn dirent_from_host(
host_entry: &nix::libc::dirent, host_entry: &nix::libc::dirent,
) -> Result<host::__wasi_dirent_t> { ) -> Result<wasi::__wasi_dirent_t> {
let mut entry = unsafe { std::mem::zeroed::<host::__wasi_dirent_t>() }; let mut entry = unsafe { std::mem::zeroed::<wasi::__wasi_dirent_t>() };
let d_namlen = unsafe { std::ffi::CStr::from_ptr(host_entry.d_name.as_ptr()) } let d_namlen = unsafe { std::ffi::CStr::from_ptr(host_entry.d_name.as_ptr()) }
.to_bytes() .to_bytes()
.len(); .len();
@@ -42,10 +42,10 @@ pub(crate) mod host_impl {
return Err(Error::EIO); return Err(Error::EIO);
} }
let d_type = dirent_filetype_from_host(host_entry)?; let d_type = dirent_filetype_from_host(host_entry)?;
entry.d_ino = memory::enc_inode(host_entry.d_ino); entry.d_ino = host_entry.d_ino;
entry.d_next = memory::enc_dircookie(host_entry.d_off as u64); entry.d_next = host_entry.d_off as u64;
entry.d_namlen = memory::enc_u32(d_namlen as u32); entry.d_namlen = d_namlen as u32;
entry.d_type = memory::enc_filetype(d_type); entry.d_type = d_type;
Ok(entry) Ok(entry)
} }
} }

View File

@@ -1,5 +1,5 @@
use crate::fdentry::Descriptor; use crate::fdentry::Descriptor;
use crate::{host, Error, Result}; use crate::{wasi, Error, Result};
use std::fs::File; use std::fs::File;
use std::io; use std::io;
use std::ops::{Deref, DerefMut}; use std::ops::{Deref, DerefMut};
@@ -49,22 +49,22 @@ impl AsRawHandle for Descriptor {
pub(crate) unsafe fn determine_type_and_access_rights<Handle: AsRawHandle>( pub(crate) unsafe fn determine_type_and_access_rights<Handle: AsRawHandle>(
handle: &Handle, handle: &Handle,
) -> Result<( ) -> Result<(
host::__wasi_filetype_t, wasi::__wasi_filetype_t,
host::__wasi_rights_t, wasi::__wasi_rights_t,
host::__wasi_rights_t, wasi::__wasi_rights_t,
)> { )> {
use winx::file::{get_file_access_mode, AccessMode}; use winx::file::{get_file_access_mode, AccessMode};
let (file_type, mut rights_base, rights_inheriting) = determine_type_rights(handle)?; let (file_type, mut rights_base, rights_inheriting) = determine_type_rights(handle)?;
match file_type { match file_type {
host::__WASI_FILETYPE_DIRECTORY | host::__WASI_FILETYPE_REGULAR_FILE => { wasi::__WASI_FILETYPE_DIRECTORY | wasi::__WASI_FILETYPE_REGULAR_FILE => {
let mode = get_file_access_mode(handle.as_raw_handle())?; let mode = get_file_access_mode(handle.as_raw_handle())?;
if mode.contains(AccessMode::FILE_GENERIC_READ) { if mode.contains(AccessMode::FILE_GENERIC_READ) {
rights_base |= host::__WASI_RIGHT_FD_READ; rights_base |= wasi::__WASI_RIGHT_FD_READ;
} }
if mode.contains(AccessMode::FILE_GENERIC_WRITE) { if mode.contains(AccessMode::FILE_GENERIC_WRITE) {
rights_base |= host::__WASI_RIGHT_FD_WRITE; rights_base |= wasi::__WASI_RIGHT_FD_WRITE;
} }
} }
_ => { _ => {
@@ -80,9 +80,9 @@ pub(crate) unsafe fn determine_type_and_access_rights<Handle: AsRawHandle>(
pub(crate) unsafe fn determine_type_rights<Handle: AsRawHandle>( pub(crate) unsafe fn determine_type_rights<Handle: AsRawHandle>(
handle: &Handle, handle: &Handle,
) -> Result<( ) -> Result<(
host::__wasi_filetype_t, wasi::__wasi_filetype_t,
host::__wasi_rights_t, wasi::__wasi_rights_t,
host::__wasi_rights_t, wasi::__wasi_rights_t,
)> { )> {
let (file_type, rights_base, rights_inheriting) = { let (file_type, rights_base, rights_inheriting) = {
let file_type = winx::file::get_file_type(handle.as_raw_handle())?; let file_type = winx::file::get_file_type(handle.as_raw_handle())?;
@@ -90,9 +90,9 @@ pub(crate) unsafe fn determine_type_rights<Handle: AsRawHandle>(
// character file: LPT device or console // character file: LPT device or console
// TODO: rule out LPT device // TODO: rule out LPT device
( (
host::__WASI_FILETYPE_CHARACTER_DEVICE, wasi::__WASI_FILETYPE_CHARACTER_DEVICE,
host::RIGHTS_TTY_BASE, wasi::RIGHTS_TTY_BASE,
host::RIGHTS_TTY_BASE, wasi::RIGHTS_TTY_BASE,
) )
} else if file_type.is_disk() { } else if file_type.is_disk() {
// disk file: file, dir or disk device // disk file: file, dir or disk device
@@ -100,15 +100,15 @@ pub(crate) unsafe fn determine_type_rights<Handle: AsRawHandle>(
let meta = file.metadata().map_err(|_| Error::EINVAL)?; let meta = file.metadata().map_err(|_| Error::EINVAL)?;
if meta.is_dir() { if meta.is_dir() {
( (
host::__WASI_FILETYPE_DIRECTORY, wasi::__WASI_FILETYPE_DIRECTORY,
host::RIGHTS_DIRECTORY_BASE, wasi::RIGHTS_DIRECTORY_BASE,
host::RIGHTS_DIRECTORY_INHERITING, wasi::RIGHTS_DIRECTORY_INHERITING,
) )
} else if meta.is_file() { } else if meta.is_file() {
( (
host::__WASI_FILETYPE_REGULAR_FILE, wasi::__WASI_FILETYPE_REGULAR_FILE,
host::RIGHTS_REGULAR_FILE_BASE, wasi::RIGHTS_REGULAR_FILE_BASE,
host::RIGHTS_REGULAR_FILE_INHERITING, wasi::RIGHTS_REGULAR_FILE_INHERITING,
) )
} else { } else {
return Err(Error::EINVAL); return Err(Error::EINVAL);
@@ -117,9 +117,9 @@ pub(crate) unsafe fn determine_type_rights<Handle: AsRawHandle>(
// pipe object: socket, named pipe or anonymous pipe // pipe object: socket, named pipe or anonymous pipe
// TODO: what about pipes, etc? // TODO: what about pipes, etc?
( (
host::__WASI_FILETYPE_SOCKET_STREAM, wasi::__WASI_FILETYPE_SOCKET_STREAM,
host::RIGHTS_SOCKET_BASE, wasi::RIGHTS_SOCKET_BASE,
host::RIGHTS_SOCKET_INHERITING, wasi::RIGHTS_SOCKET_INHERITING,
) )
} else { } else {
return Err(Error::EINVAL); return Err(Error::EINVAL);

View File

@@ -2,54 +2,54 @@
#![allow(non_camel_case_types)] #![allow(non_camel_case_types)]
#![allow(non_snake_case)] #![allow(non_snake_case)]
#![allow(unused)] #![allow(unused)]
use crate::{host, Error, Result}; use crate::{wasi, Error, Result};
use std::ffi::OsStr; use std::ffi::OsStr;
use std::fs::OpenOptions; use std::fs::OpenOptions;
use std::os::windows::ffi::OsStrExt; use std::os::windows::ffi::OsStrExt;
use std::os::windows::fs::OpenOptionsExt; use std::os::windows::fs::OpenOptionsExt;
use winx::file::{AccessMode, Attributes, CreationDisposition, Flags}; use winx::file::{AccessMode, Attributes, CreationDisposition, Flags};
pub(crate) fn errno_from_win(error: winx::winerror::WinError) -> host::__wasi_errno_t { pub(crate) fn errno_from_win(error: winx::winerror::WinError) -> wasi::__wasi_errno_t {
// TODO: implement error mapping between Windows and WASI // TODO: implement error mapping between Windows and WASI
use winx::winerror::WinError::*; use winx::winerror::WinError::*;
match error { match error {
ERROR_SUCCESS => host::__WASI_ESUCCESS, ERROR_SUCCESS => wasi::__WASI_ESUCCESS,
ERROR_BAD_ENVIRONMENT => host::__WASI_E2BIG, ERROR_BAD_ENVIRONMENT => wasi::__WASI_E2BIG,
ERROR_FILE_NOT_FOUND => host::__WASI_ENOENT, ERROR_FILE_NOT_FOUND => wasi::__WASI_ENOENT,
ERROR_PATH_NOT_FOUND => host::__WASI_ENOENT, ERROR_PATH_NOT_FOUND => wasi::__WASI_ENOENT,
ERROR_TOO_MANY_OPEN_FILES => host::__WASI_ENFILE, ERROR_TOO_MANY_OPEN_FILES => wasi::__WASI_ENFILE,
ERROR_ACCESS_DENIED => host::__WASI_EACCES, ERROR_ACCESS_DENIED => wasi::__WASI_EACCES,
ERROR_SHARING_VIOLATION => host::__WASI_EACCES, ERROR_SHARING_VIOLATION => wasi::__WASI_EACCES,
ERROR_PRIVILEGE_NOT_HELD => host::__WASI_ENOTCAPABLE, // TODO is this the correct mapping? ERROR_PRIVILEGE_NOT_HELD => wasi::__WASI_ENOTCAPABLE, // TODO is this the correct mapping?
ERROR_INVALID_HANDLE => host::__WASI_EBADF, ERROR_INVALID_HANDLE => wasi::__WASI_EBADF,
ERROR_INVALID_NAME => host::__WASI_ENOENT, ERROR_INVALID_NAME => wasi::__WASI_ENOENT,
ERROR_NOT_ENOUGH_MEMORY => host::__WASI_ENOMEM, ERROR_NOT_ENOUGH_MEMORY => wasi::__WASI_ENOMEM,
ERROR_OUTOFMEMORY => host::__WASI_ENOMEM, ERROR_OUTOFMEMORY => wasi::__WASI_ENOMEM,
ERROR_DIR_NOT_EMPTY => host::__WASI_ENOTEMPTY, ERROR_DIR_NOT_EMPTY => wasi::__WASI_ENOTEMPTY,
ERROR_NOT_READY => host::__WASI_EBUSY, ERROR_NOT_READY => wasi::__WASI_EBUSY,
ERROR_BUSY => host::__WASI_EBUSY, ERROR_BUSY => wasi::__WASI_EBUSY,
ERROR_NOT_SUPPORTED => host::__WASI_ENOTSUP, ERROR_NOT_SUPPORTED => wasi::__WASI_ENOTSUP,
ERROR_FILE_EXISTS => host::__WASI_EEXIST, ERROR_FILE_EXISTS => wasi::__WASI_EEXIST,
ERROR_BROKEN_PIPE => host::__WASI_EPIPE, ERROR_BROKEN_PIPE => wasi::__WASI_EPIPE,
ERROR_BUFFER_OVERFLOW => host::__WASI_ENAMETOOLONG, ERROR_BUFFER_OVERFLOW => wasi::__WASI_ENAMETOOLONG,
ERROR_NOT_A_REPARSE_POINT => host::__WASI_EINVAL, ERROR_NOT_A_REPARSE_POINT => wasi::__WASI_EINVAL,
ERROR_NEGATIVE_SEEK => host::__WASI_EINVAL, ERROR_NEGATIVE_SEEK => wasi::__WASI_EINVAL,
ERROR_DIRECTORY => host::__WASI_ENOTDIR, ERROR_DIRECTORY => wasi::__WASI_ENOTDIR,
ERROR_ALREADY_EXISTS => host::__WASI_EEXIST, ERROR_ALREADY_EXISTS => wasi::__WASI_EEXIST,
_ => host::__WASI_ENOTSUP, _ => wasi::__WASI_ENOTSUP,
} }
} }
pub(crate) fn fdflags_from_win(mode: AccessMode) -> host::__wasi_fdflags_t { pub(crate) fn fdflags_from_win(mode: AccessMode) -> wasi::__wasi_fdflags_t {
let mut fdflags = 0; let mut fdflags = 0;
// TODO verify this! // TODO verify this!
if mode.contains(AccessMode::FILE_APPEND_DATA) { if mode.contains(AccessMode::FILE_APPEND_DATA) {
fdflags |= host::__WASI_FDFLAG_APPEND; fdflags |= wasi::__WASI_FDFLAG_APPEND;
} }
if mode.contains(AccessMode::SYNCHRONIZE) { if mode.contains(AccessMode::SYNCHRONIZE) {
fdflags |= host::__WASI_FDFLAG_DSYNC; fdflags |= wasi::__WASI_FDFLAG_DSYNC;
fdflags |= host::__WASI_FDFLAG_RSYNC; fdflags |= wasi::__WASI_FDFLAG_RSYNC;
fdflags |= host::__WASI_FDFLAG_SYNC; fdflags |= wasi::__WASI_FDFLAG_SYNC;
} }
// The NONBLOCK equivalent is FILE_FLAG_OVERLAPPED // The NONBLOCK equivalent is FILE_FLAG_OVERLAPPED
// but it seems winapi doesn't provide a mechanism // but it seems winapi doesn't provide a mechanism
@@ -63,20 +63,20 @@ pub(crate) fn fdflags_from_win(mode: AccessMode) -> host::__wasi_fdflags_t {
fdflags fdflags
} }
pub(crate) fn win_from_fdflags(fdflags: host::__wasi_fdflags_t) -> (AccessMode, Flags) { pub(crate) fn win_from_fdflags(fdflags: wasi::__wasi_fdflags_t) -> (AccessMode, Flags) {
let mut access_mode = AccessMode::empty(); let mut access_mode = AccessMode::empty();
let mut flags = Flags::empty(); let mut flags = Flags::empty();
// TODO verify this! // TODO verify this!
if fdflags & host::__WASI_FDFLAG_NONBLOCK != 0 { if fdflags & wasi::__WASI_FDFLAG_NONBLOCK != 0 {
flags.insert(Flags::FILE_FLAG_OVERLAPPED); flags.insert(Flags::FILE_FLAG_OVERLAPPED);
} }
if fdflags & host::__WASI_FDFLAG_APPEND != 0 { if fdflags & wasi::__WASI_FDFLAG_APPEND != 0 {
access_mode.insert(AccessMode::FILE_APPEND_DATA); access_mode.insert(AccessMode::FILE_APPEND_DATA);
} }
if fdflags & host::__WASI_FDFLAG_DSYNC != 0 if fdflags & wasi::__WASI_FDFLAG_DSYNC != 0
|| fdflags & host::__WASI_FDFLAG_RSYNC != 0 || fdflags & wasi::__WASI_FDFLAG_RSYNC != 0
|| fdflags & host::__WASI_FDFLAG_SYNC != 0 || fdflags & wasi::__WASI_FDFLAG_SYNC != 0
{ {
access_mode.insert(AccessMode::SYNCHRONIZE); access_mode.insert(AccessMode::SYNCHRONIZE);
} }
@@ -84,14 +84,14 @@ pub(crate) fn win_from_fdflags(fdflags: host::__wasi_fdflags_t) -> (AccessMode,
(access_mode, flags) (access_mode, flags)
} }
pub(crate) fn win_from_oflags(oflags: host::__wasi_oflags_t) -> CreationDisposition { pub(crate) fn win_from_oflags(oflags: wasi::__wasi_oflags_t) -> CreationDisposition {
if oflags & host::__WASI_O_CREAT != 0 { if oflags & wasi::__WASI_O_CREAT != 0 {
if oflags & host::__WASI_O_EXCL != 0 { if oflags & wasi::__WASI_O_EXCL != 0 {
CreationDisposition::CREATE_NEW CreationDisposition::CREATE_NEW
} else { } else {
CreationDisposition::CREATE_ALWAYS CreationDisposition::CREATE_ALWAYS
} }
} else if oflags & host::__WASI_O_TRUNC != 0 { } else if oflags & wasi::__WASI_O_TRUNC != 0 {
CreationDisposition::TRUNCATE_EXISTING CreationDisposition::TRUNCATE_EXISTING
} else { } else {
CreationDisposition::OPEN_EXISTING CreationDisposition::OPEN_EXISTING

View File

@@ -8,7 +8,7 @@ use crate::hostcalls_impl::{fd_filestat_set_times_impl, FileType, PathGet};
use crate::sys::fdentry_impl::{determine_type_rights, OsFile}; use crate::sys::fdentry_impl::{determine_type_rights, OsFile};
use crate::sys::host_impl; use crate::sys::host_impl;
use crate::sys::hostcalls_impl::fs_helpers::PathGetExt; use crate::sys::hostcalls_impl::fs_helpers::PathGetExt;
use crate::{host, Error, Result}; use crate::{wasi, Error, Result};
use std::convert::TryInto; use std::convert::TryInto;
use std::fs::{File, Metadata, OpenOptions}; use std::fs::{File, Metadata, OpenOptions};
use std::io::{self, Seek, SeekFrom}; use std::io::{self, Seek, SeekFrom};
@@ -40,40 +40,40 @@ fn write_at(mut file: &File, buf: &[u8], offset: u64) -> io::Result<usize> {
pub(crate) fn fd_pread( pub(crate) fn fd_pread(
file: &File, file: &File,
buf: &mut [u8], buf: &mut [u8],
offset: host::__wasi_filesize_t, offset: wasi::__wasi_filesize_t,
) -> Result<usize> { ) -> Result<usize> {
read_at(file, buf, offset).map_err(Into::into) read_at(file, buf, offset).map_err(Into::into)
} }
// TODO refactor common code with unix // TODO refactor common code with unix
pub(crate) fn fd_pwrite(file: &File, buf: &[u8], offset: host::__wasi_filesize_t) -> Result<usize> { pub(crate) fn fd_pwrite(file: &File, buf: &[u8], offset: wasi::__wasi_filesize_t) -> Result<usize> {
write_at(file, buf, offset).map_err(Into::into) write_at(file, buf, offset).map_err(Into::into)
} }
pub(crate) fn fd_fdstat_get(fd: &File) -> Result<host::__wasi_fdflags_t> { pub(crate) fn fd_fdstat_get(fd: &File) -> Result<wasi::__wasi_fdflags_t> {
use winx::file::AccessMode; use winx::file::AccessMode;
unsafe { winx::file::get_file_access_mode(fd.as_raw_handle()) } unsafe { winx::file::get_file_access_mode(fd.as_raw_handle()) }
.map(host_impl::fdflags_from_win) .map(host_impl::fdflags_from_win)
.map_err(Into::into) .map_err(Into::into)
} }
pub(crate) fn fd_fdstat_set_flags(fd: &File, fdflags: host::__wasi_fdflags_t) -> Result<()> { pub(crate) fn fd_fdstat_set_flags(fd: &File, fdflags: wasi::__wasi_fdflags_t) -> Result<()> {
unimplemented!("fd_fdstat_set_flags") unimplemented!("fd_fdstat_set_flags")
} }
pub(crate) fn fd_advise( pub(crate) fn fd_advise(
_file: &File, _file: &File,
advice: host::__wasi_advice_t, advice: wasi::__wasi_advice_t,
_offset: host::__wasi_filesize_t, _offset: wasi::__wasi_filesize_t,
_len: host::__wasi_filesize_t, _len: wasi::__wasi_filesize_t,
) -> Result<()> { ) -> Result<()> {
match advice { match advice {
host::__WASI_ADVICE_DONTNEED wasi::__WASI_ADVICE_DONTNEED
| host::__WASI_ADVICE_SEQUENTIAL | wasi::__WASI_ADVICE_SEQUENTIAL
| host::__WASI_ADVICE_WILLNEED | wasi::__WASI_ADVICE_WILLNEED
| host::__WASI_ADVICE_NOREUSE | wasi::__WASI_ADVICE_NOREUSE
| host::__WASI_ADVICE_RANDOM | wasi::__WASI_ADVICE_RANDOM
| host::__WASI_ADVICE_NORMAL => {} | wasi::__WASI_ADVICE_NORMAL => {}
_ => return Err(Error::EINVAL), _ => return Err(Error::EINVAL),
} }
@@ -93,8 +93,8 @@ pub(crate) fn path_open(
resolved: PathGet, resolved: PathGet,
read: bool, read: bool,
write: bool, write: bool,
oflags: host::__wasi_oflags_t, oflags: wasi::__wasi_oflags_t,
fdflags: host::__wasi_fdflags_t, fdflags: wasi::__wasi_fdflags_t,
) -> Result<File> { ) -> Result<File> {
use winx::file::{AccessMode, CreationDisposition, Flags}; use winx::file::{AccessMode, CreationDisposition, Flags};
@@ -137,7 +137,7 @@ pub(crate) fn path_open(
return Err(Error::ELOOP); return Err(Error::ELOOP);
} }
// check if we are trying to open a file as a dir // check if we are trying to open a file as a dir
if file_type.is_file() && oflags & host::__WASI_O_DIRECTORY != 0 { if file_type.is_file() && oflags & wasi::__WASI_O_DIRECTORY != 0 {
return Err(Error::ENOTDIR); return Err(Error::ENOTDIR);
} }
} }
@@ -169,7 +169,7 @@ pub(crate) fn path_open(
pub(crate) fn fd_readdir( pub(crate) fn fd_readdir(
fd: &mut OsFile, fd: &mut OsFile,
host_buf: &mut [u8], host_buf: &mut [u8],
cookie: host::__wasi_dircookie_t, cookie: wasi::__wasi_dircookie_t,
) -> Result<usize> { ) -> Result<usize> {
unimplemented!("fd_readdir") unimplemented!("fd_readdir")
} }
@@ -276,9 +276,9 @@ pub(crate) fn change_time(file: &File, _metadata: &Metadata) -> io::Result<i64>
winx::file::change_time(file) winx::file::change_time(file)
} }
pub(crate) fn fd_filestat_get_impl(file: &std::fs::File) -> Result<host::__wasi_filestat_t> { pub(crate) fn fd_filestat_get_impl(file: &std::fs::File) -> Result<wasi::__wasi_filestat_t> {
let metadata = file.metadata()?; let metadata = file.metadata()?;
Ok(host::__wasi_filestat_t { Ok(wasi::__wasi_filestat_t {
st_dev: device_id(file, &metadata)?, st_dev: device_id(file, &metadata)?,
st_ino: file_serial_no(file, &metadata)?, st_ino: file_serial_no(file, &metadata)?,
st_nlink: num_hardlinks(file, &metadata)?.try_into()?, // u64 doesn't fit into u32 st_nlink: num_hardlinks(file, &metadata)?.try_into()?, // u64 doesn't fit into u32
@@ -307,8 +307,8 @@ fn filetype(_file: &File, metadata: &Metadata) -> Result<FileType> {
pub(crate) fn path_filestat_get( pub(crate) fn path_filestat_get(
resolved: PathGet, resolved: PathGet,
dirflags: host::__wasi_lookupflags_t, dirflags: wasi::__wasi_lookupflags_t,
) -> Result<host::__wasi_filestat_t> { ) -> Result<wasi::__wasi_filestat_t> {
let path = resolved.concatenate()?; let path = resolved.concatenate()?;
let file = File::open(path)?; let file = File::open(path)?;
fd_filestat_get_impl(&file) fd_filestat_get_impl(&file)
@@ -316,10 +316,10 @@ pub(crate) fn path_filestat_get(
pub(crate) fn path_filestat_set_times( pub(crate) fn path_filestat_set_times(
resolved: PathGet, resolved: PathGet,
dirflags: host::__wasi_lookupflags_t, dirflags: wasi::__wasi_lookupflags_t,
st_atim: host::__wasi_timestamp_t, st_atim: wasi::__wasi_timestamp_t,
mut st_mtim: host::__wasi_timestamp_t, mut st_mtim: wasi::__wasi_timestamp_t,
fst_flags: host::__wasi_fstflags_t, fst_flags: wasi::__wasi_fstflags_t,
) -> Result<()> { ) -> Result<()> {
use winx::file::AccessMode; use winx::file::AccessMode;
let path = resolved.concatenate()?; let path = resolved.concatenate()?;

View File

@@ -1,6 +1,6 @@
#![allow(non_camel_case_types)] #![allow(non_camel_case_types)]
use crate::hostcalls_impl::PathGet; use crate::hostcalls_impl::PathGet;
use crate::{host, Error, Result}; use crate::{wasi, Error, Result};
use std::ffi::{OsStr, OsString}; use std::ffi::{OsStr, OsString};
use std::fs::File; use std::fs::File;
use std::os::windows::ffi::{OsStrExt, OsStringExt}; use std::os::windows::ffi::{OsStrExt, OsStringExt};
@@ -17,29 +17,29 @@ impl PathGetExt for PathGet {
} }
pub(crate) fn path_open_rights( pub(crate) fn path_open_rights(
rights_base: host::__wasi_rights_t, rights_base: wasi::__wasi_rights_t,
rights_inheriting: host::__wasi_rights_t, rights_inheriting: wasi::__wasi_rights_t,
oflags: host::__wasi_oflags_t, oflags: wasi::__wasi_oflags_t,
fdflags: host::__wasi_fdflags_t, fdflags: wasi::__wasi_fdflags_t,
) -> (host::__wasi_rights_t, host::__wasi_rights_t) { ) -> (wasi::__wasi_rights_t, wasi::__wasi_rights_t) {
// which rights are needed on the dirfd? // which rights are needed on the dirfd?
let mut needed_base = host::__WASI_RIGHT_PATH_OPEN; let mut needed_base = wasi::__WASI_RIGHT_PATH_OPEN;
let mut needed_inheriting = rights_base | rights_inheriting; let mut needed_inheriting = rights_base | rights_inheriting;
// convert open flags // convert open flags
if oflags & host::__WASI_O_CREAT != 0 { if oflags & wasi::__WASI_O_CREAT != 0 {
needed_base |= host::__WASI_RIGHT_PATH_CREATE_FILE; needed_base |= wasi::__WASI_RIGHT_PATH_CREATE_FILE;
} else if oflags & host::__WASI_O_TRUNC != 0 { } else if oflags & wasi::__WASI_O_TRUNC != 0 {
needed_base |= host::__WASI_RIGHT_PATH_FILESTAT_SET_SIZE; needed_base |= wasi::__WASI_RIGHT_PATH_FILESTAT_SET_SIZE;
} }
// convert file descriptor flags // convert file descriptor flags
if fdflags & host::__WASI_FDFLAG_DSYNC != 0 if fdflags & wasi::__WASI_FDFLAG_DSYNC != 0
|| fdflags & host::__WASI_FDFLAG_RSYNC != 0 || fdflags & wasi::__WASI_FDFLAG_RSYNC != 0
|| fdflags & host::__WASI_FDFLAG_SYNC != 0 || fdflags & wasi::__WASI_FDFLAG_SYNC != 0
{ {
needed_inheriting |= host::__WASI_RIGHT_FD_DATASYNC; needed_inheriting |= wasi::__WASI_RIGHT_FD_DATASYNC;
needed_inheriting |= host::__WASI_RIGHT_FD_SYNC; needed_inheriting |= wasi::__WASI_RIGHT_FD_SYNC;
} }
(needed_base, needed_inheriting) (needed_base, needed_inheriting)

View File

@@ -5,7 +5,7 @@ use crate::helpers::systemtime_to_timestamp;
use crate::hostcalls_impl::{ClockEventData, FdEventData}; use crate::hostcalls_impl::{ClockEventData, FdEventData};
use crate::memory::*; use crate::memory::*;
use crate::sys::host_impl; use crate::sys::host_impl;
use crate::{host, wasm32, Error, Result}; use crate::{wasi, wasi32, Error, Result};
use cpu_time::{ProcessTime, ThreadTime}; use cpu_time::{ProcessTime, ThreadTime};
use lazy_static::lazy_static; use lazy_static::lazy_static;
use std::convert::TryInto; use std::convert::TryInto;
@@ -15,16 +15,16 @@ lazy_static! {
static ref START_MONOTONIC: Instant = Instant::now(); static ref START_MONOTONIC: Instant = Instant::now();
} }
pub(crate) fn clock_res_get(clock_id: host::__wasi_clockid_t) -> Result<host::__wasi_timestamp_t> { pub(crate) fn clock_res_get(clock_id: wasi::__wasi_clockid_t) -> Result<wasi::__wasi_timestamp_t> {
unimplemented!("clock_res_get") unimplemented!("clock_res_get")
} }
pub(crate) fn clock_time_get(clock_id: host::__wasi_clockid_t) -> Result<host::__wasi_timestamp_t> { pub(crate) fn clock_time_get(clock_id: wasi::__wasi_clockid_t) -> Result<wasi::__wasi_timestamp_t> {
let duration = match clock_id { let duration = match clock_id {
host::__WASI_CLOCK_REALTIME => get_monotonic_time(), wasi::__WASI_CLOCK_REALTIME => get_monotonic_time(),
host::__WASI_CLOCK_MONOTONIC => get_realtime_time()?, wasi::__WASI_CLOCK_MONOTONIC => get_realtime_time()?,
host::__WASI_CLOCK_PROCESS_CPUTIME_ID => get_proc_cputime()?, wasi::__WASI_CLOCK_PROCESS_CPUTIME_ID => get_proc_cputime()?,
host::__WASI_CLOCK_THREAD_CPUTIME_ID => get_thread_cputime()?, wasi::__WASI_CLOCK_THREAD_CPUTIME_ID => get_thread_cputime()?,
_ => return Err(Error::EINVAL), _ => return Err(Error::EINVAL),
}; };
duration.as_nanos().try_into().map_err(Into::into) duration.as_nanos().try_into().map_err(Into::into)
@@ -33,7 +33,8 @@ pub(crate) fn clock_time_get(clock_id: host::__wasi_clockid_t) -> Result<host::_
pub(crate) fn poll_oneoff( pub(crate) fn poll_oneoff(
timeout: Option<ClockEventData>, timeout: Option<ClockEventData>,
fd_events: Vec<FdEventData>, fd_events: Vec<FdEventData>,
) -> Result<Vec<host::__wasi_event_t>> { events: &mut Vec<wasi::__wasi_event_t>,
) -> Result<Vec<wasi::__wasi_event_t>> {
unimplemented!("poll_oneoff") unimplemented!("poll_oneoff")
} }

View File

@@ -1,9 +1,6 @@
//! WASI types as defined in wasm32. This file was originally generated //! Types and constants shared between 32-bit and 64-bit wasi. Types involving
//! by running bindgen over wasi/core.h with a wasm32 target, and the content //! pointer or `usize`-sized data are excluded here, so this file only contains
//! still largely reflects that, however it's been heavily modified, to //! fixed-size types, so it's host/target independent.
//! be host-independent, to avoid exposing libc implementation details,
//! to clean up cases where the headers use complex preprocessor macros,
//! and to
#![allow(non_camel_case_types)] #![allow(non_camel_case_types)]
#![allow(non_snake_case)] #![allow(non_snake_case)]
@@ -17,8 +14,6 @@ pub type short = i16;
pub type ushort = u16; pub type ushort = u16;
pub type int = i32; pub type int = i32;
pub type uint = u32; pub type uint = u32;
pub type long = i32;
pub type ulong = u32;
pub type longlong = i64; pub type longlong = i64;
pub type ulonglong = u64; pub type ulonglong = u64;
@@ -49,9 +44,6 @@ pub type uint_fast8_t = u8;
pub type uint_fast16_t = u32; pub type uint_fast16_t = u32;
pub type uint_fast32_t = u32; pub type uint_fast32_t = u32;
pub type uint_fast64_t = u64; pub type uint_fast64_t = u64;
pub type size_t = ulong;
pub type intptr_t = long;
pub type uintptr_t = ulong;
pub type wchar_t = i32; pub type wchar_t = i32;
// libc types // libc types
@@ -75,7 +67,6 @@ pub type suseconds_t = i64;
pub type daddr_t = i32; pub type daddr_t = i32;
pub type key_t = i32; pub type key_t = i32;
pub type clockid_t = i32; pub type clockid_t = i32;
pub type timer_t = uintptr_t; // *mut ::std::os::raw::c_void
pub type blksize_t = i64; pub type blksize_t = i64;
pub type blkcnt_t = i64; pub type blkcnt_t = i64;
pub type blkcnt64_t = i64; pub type blkcnt64_t = i64;
@@ -86,7 +77,6 @@ pub type fsfilcnt64_t = u64;
pub type fsword_t = i64; pub type fsword_t = i64;
pub type ssize_t = i32; pub type ssize_t = i32;
pub type loff_t = off64_t; pub type loff_t = off64_t;
pub type caddr_t = uintptr_t; // *mut i8
pub type socklen_t = u32; pub type socklen_t = u32;
pub type sig_atomic_t = i32; pub type sig_atomic_t = i32;
@@ -128,6 +118,112 @@ pub type __wasi_timestamp_t = u64;
pub type __wasi_userdata_t = u64; pub type __wasi_userdata_t = u64;
pub type __wasi_whence_t = u8; pub type __wasi_whence_t = u8;
pub(crate) const RIGHTS_ALL: __wasi_rights_t = __WASI_RIGHT_FD_DATASYNC
| __WASI_RIGHT_FD_READ
| __WASI_RIGHT_FD_SEEK
| __WASI_RIGHT_FD_FDSTAT_SET_FLAGS
| __WASI_RIGHT_FD_SYNC
| __WASI_RIGHT_FD_TELL
| __WASI_RIGHT_FD_WRITE
| __WASI_RIGHT_FD_ADVISE
| __WASI_RIGHT_FD_ALLOCATE
| __WASI_RIGHT_PATH_CREATE_DIRECTORY
| __WASI_RIGHT_PATH_CREATE_FILE
| __WASI_RIGHT_PATH_LINK_SOURCE
| __WASI_RIGHT_PATH_LINK_TARGET
| __WASI_RIGHT_PATH_OPEN
| __WASI_RIGHT_FD_READDIR
| __WASI_RIGHT_PATH_READLINK
| __WASI_RIGHT_PATH_RENAME_SOURCE
| __WASI_RIGHT_PATH_RENAME_TARGET
| __WASI_RIGHT_PATH_FILESTAT_GET
| __WASI_RIGHT_PATH_FILESTAT_SET_SIZE
| __WASI_RIGHT_PATH_FILESTAT_SET_TIMES
| __WASI_RIGHT_FD_FILESTAT_GET
| __WASI_RIGHT_FD_FILESTAT_SET_SIZE
| __WASI_RIGHT_FD_FILESTAT_SET_TIMES
| __WASI_RIGHT_PATH_SYMLINK
| __WASI_RIGHT_PATH_UNLINK_FILE
| __WASI_RIGHT_PATH_REMOVE_DIRECTORY
| __WASI_RIGHT_POLL_FD_READWRITE
| __WASI_RIGHT_SOCK_SHUTDOWN;
// Block and character device interaction is outside the scope of
// WASI. Simply allow everything.
pub(crate) const RIGHTS_BLOCK_DEVICE_BASE: __wasi_rights_t = RIGHTS_ALL;
pub(crate) const RIGHTS_BLOCK_DEVICE_INHERITING: __wasi_rights_t = RIGHTS_ALL;
pub(crate) const RIGHTS_CHARACTER_DEVICE_BASE: __wasi_rights_t = RIGHTS_ALL;
pub(crate) const RIGHTS_CHARACTER_DEVICE_INHERITING: __wasi_rights_t = RIGHTS_ALL;
// Only allow directory operations on directories. Directories can only
// yield file descriptors to other directories and files.
pub(crate) const RIGHTS_DIRECTORY_BASE: __wasi_rights_t = __WASI_RIGHT_FD_FDSTAT_SET_FLAGS
| __WASI_RIGHT_FD_SYNC
| __WASI_RIGHT_FD_ADVISE
| __WASI_RIGHT_PATH_CREATE_DIRECTORY
| __WASI_RIGHT_PATH_CREATE_FILE
| __WASI_RIGHT_PATH_LINK_SOURCE
| __WASI_RIGHT_PATH_LINK_TARGET
| __WASI_RIGHT_PATH_OPEN
| __WASI_RIGHT_FD_READDIR
| __WASI_RIGHT_PATH_READLINK
| __WASI_RIGHT_PATH_RENAME_SOURCE
| __WASI_RIGHT_PATH_RENAME_TARGET
| __WASI_RIGHT_PATH_FILESTAT_GET
| __WASI_RIGHT_PATH_FILESTAT_SET_SIZE
| __WASI_RIGHT_PATH_FILESTAT_SET_TIMES
| __WASI_RIGHT_FD_FILESTAT_GET
| __WASI_RIGHT_FD_FILESTAT_SET_TIMES
| __WASI_RIGHT_PATH_SYMLINK
| __WASI_RIGHT_PATH_UNLINK_FILE
| __WASI_RIGHT_PATH_REMOVE_DIRECTORY
| __WASI_RIGHT_POLL_FD_READWRITE;
pub(crate) const RIGHTS_DIRECTORY_INHERITING: __wasi_rights_t =
RIGHTS_DIRECTORY_BASE | RIGHTS_REGULAR_FILE_BASE;
// Operations that apply to regular files.
pub(crate) const RIGHTS_REGULAR_FILE_BASE: __wasi_rights_t = __WASI_RIGHT_FD_DATASYNC
| __WASI_RIGHT_FD_READ
| __WASI_RIGHT_FD_SEEK
| __WASI_RIGHT_FD_FDSTAT_SET_FLAGS
| __WASI_RIGHT_FD_SYNC
| __WASI_RIGHT_FD_TELL
| __WASI_RIGHT_FD_WRITE
| __WASI_RIGHT_FD_ADVISE
| __WASI_RIGHT_FD_ALLOCATE
| __WASI_RIGHT_FD_FILESTAT_GET
| __WASI_RIGHT_FD_FILESTAT_SET_SIZE
| __WASI_RIGHT_FD_FILESTAT_SET_TIMES
| __WASI_RIGHT_POLL_FD_READWRITE;
pub(crate) const RIGHTS_REGULAR_FILE_INHERITING: __wasi_rights_t = 0;
// Operations that apply to shared memory objects.
#[allow(unused)]
pub(crate) const RIGHTS_SHARED_MEMORY_BASE: __wasi_rights_t = __WASI_RIGHT_FD_READ
| __WASI_RIGHT_FD_WRITE
| __WASI_RIGHT_FD_FILESTAT_GET
| __WASI_RIGHT_FD_FILESTAT_SET_SIZE;
#[allow(unused)]
pub(crate) const RIGHTS_SHARED_MEMORY_INHERITING: __wasi_rights_t = 0;
// Operations that apply to sockets and socket pairs.
pub(crate) const RIGHTS_SOCKET_BASE: __wasi_rights_t = __WASI_RIGHT_FD_READ
| __WASI_RIGHT_FD_FDSTAT_SET_FLAGS
| __WASI_RIGHT_FD_WRITE
| __WASI_RIGHT_FD_FILESTAT_GET
| __WASI_RIGHT_POLL_FD_READWRITE
| __WASI_RIGHT_SOCK_SHUTDOWN;
pub(crate) const RIGHTS_SOCKET_INHERITING: __wasi_rights_t = RIGHTS_ALL;
// Operations that apply to TTYs.
pub(crate) const RIGHTS_TTY_BASE: __wasi_rights_t = __WASI_RIGHT_FD_READ
| __WASI_RIGHT_FD_FDSTAT_SET_FLAGS
| __WASI_RIGHT_FD_WRITE
| __WASI_RIGHT_FD_FILESTAT_GET
| __WASI_RIGHT_POLL_FD_READWRITE;
#[allow(unused)]
pub(crate) const RIGHTS_TTY_INHERITING: __wasi_rights_t = 0;
#[repr(C)] #[repr(C)]
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone)]
pub struct __wasi_dirent_t { pub struct __wasi_dirent_t {
@@ -163,25 +259,6 @@ pub struct __wasi_event_t___wasi_event_u___wasi_event_u_fd_readwrite_t {
pub __bindgen_padding_0: [u16; 3usize], pub __bindgen_padding_0: [u16; 3usize],
} }
#[repr(C)]
#[derive(Copy, Clone)]
pub struct __wasi_prestat_t {
pub pr_type: __wasi_preopentype_t,
pub u: __wasi_prestat_t___wasi_prestat_u,
}
#[repr(C)]
#[derive(Copy, Clone)]
pub union __wasi_prestat_t___wasi_prestat_u {
pub dir: __wasi_prestat_t___wasi_prestat_u___wasi_prestat_u_dir_t,
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct __wasi_prestat_t___wasi_prestat_u___wasi_prestat_u_dir_t {
pub pr_name_len: size_t,
}
#[repr(C)] #[repr(C)]
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
pub union __wasi_event_t__bindgen_ty_1 { pub union __wasi_event_t__bindgen_ty_1 {
@@ -227,20 +304,6 @@ pub struct __wasi_filestat_t {
pub st_ctim: __wasi_timestamp_t, pub st_ctim: __wasi_timestamp_t,
} }
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct __wasi_ciovec_t {
pub buf: uintptr_t, // *const ::std::os::raw::c_void
pub buf_len: size_t,
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct __wasi_iovec_t {
pub buf: uintptr_t, // *mut ::std::os::raw::c_void
pub buf_len: size_t,
}
#[repr(C)] #[repr(C)]
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
pub struct __wasi_subscription_t { pub struct __wasi_subscription_t {
@@ -397,14 +460,6 @@ pub const INT_FAST32_MAX: u32 = 2147483647;
pub const UINT_FAST8_MAX: u32 = 255; pub const UINT_FAST8_MAX: u32 = 255;
pub const UINT_FAST16_MAX: u32 = 4294967295; pub const UINT_FAST16_MAX: u32 = 4294967295;
pub const UINT_FAST32_MAX: u32 = 4294967295; pub const UINT_FAST32_MAX: u32 = 4294967295;
pub const INTPTR_MIN: i32 = -2147483648;
pub const INTPTR_MAX: u32 = 2147483647;
pub const UINTPTR_MAX: u32 = 4294967295;
pub const PTRDIFF_MIN: i32 = -2147483648;
pub const PTRDIFF_MAX: u32 = 2147483647;
pub const SIG_ATOMIC_MIN: i32 = -2147483648;
pub const SIG_ATOMIC_MAX: u32 = 2147483647;
pub const SIZE_MAX: u32 = 4294967295;
pub const WINT_MIN: i32 = -2147483648; pub const WINT_MIN: i32 = -2147483648;
pub const WINT_MAX: i32 = 2147483647; pub const WINT_MAX: i32 = 2147483647;
@@ -799,103 +854,6 @@ mod test {
); );
} }
#[test]
fn bindgen_test_layout___wasi_prestat_t___wasi_prestat_u___wasi_prestat_u_dir_t() {
assert_eq!(
::std::mem::size_of::<__wasi_prestat_t___wasi_prestat_u___wasi_prestat_u_dir_t>(),
4usize,
concat!(
"Size of: ",
stringify!(__wasi_prestat_t___wasi_prestat_u___wasi_prestat_u_dir_t)
)
);
assert_eq!(
::std::mem::align_of::<__wasi_prestat_t___wasi_prestat_u___wasi_prestat_u_dir_t>(),
4usize,
concat!(
"Alignment of ",
stringify!(__wasi_prestat_t___wasi_prestat_u___wasi_prestat_u_dir_t)
)
);
assert_eq!(
unsafe {
&(*(::std::ptr::null::<__wasi_prestat_t___wasi_prestat_u___wasi_prestat_u_dir_t>()))
.pr_name_len as *const _ as usize
},
0usize,
concat!(
"Offset of field: ",
stringify!(__wasi_prestat_t___wasi_prestat_u___wasi_prestat_u_dir_t),
"::",
stringify!(pr_name_len)
)
);
}
#[test]
fn bindgen_test_layout___wasi_prestat_t___wasi_prestat_u() {
assert_eq!(
::std::mem::size_of::<__wasi_prestat_t___wasi_prestat_u>(),
4usize,
concat!("Size of: ", stringify!(__wasi_prestat_t___wasi_prestat_u))
);
assert_eq!(
::std::mem::align_of::<__wasi_prestat_t___wasi_prestat_u>(),
4usize,
concat!(
"Alignment of ",
stringify!(__wasi_prestat_t___wasi_prestat_u)
)
);
assert_eq!(
unsafe {
&(*(::std::ptr::null::<__wasi_prestat_t___wasi_prestat_u>())).dir as *const _
as usize
},
0usize,
concat!(
"Offset of field: ",
stringify!(__wasi_prestat_t___wasi_prestat_u),
"::",
stringify!(dir)
)
);
}
#[test]
fn bindgen_test_layout___wasi_prestat_t() {
assert_eq!(
::std::mem::size_of::<__wasi_prestat_t>(),
8usize,
concat!("Size of: ", stringify!(__wasi_prestat_t))
);
assert_eq!(
::std::mem::align_of::<__wasi_prestat_t>(),
4usize,
concat!("Alignment of ", stringify!(__wasi_prestat_t))
);
assert_eq!(
unsafe { &(*(::std::ptr::null::<__wasi_prestat_t>())).pr_type as *const _ as usize },
0usize,
concat!(
"Offset of field: ",
stringify!(__wasi_prestat_t),
"::",
stringify!(pr_type)
)
);
assert_eq!(
unsafe { &(*(::std::ptr::null::<__wasi_prestat_t>())).u as *const _ as usize },
4usize,
concat!(
"Offset of field: ",
stringify!(__wasi_prestat_t),
"::",
stringify!(u)
)
);
}
#[test] #[test]
fn bindgen_test_layout_wasi_event_t__bindgen_ty_1__bindgen_ty_1() { fn bindgen_test_layout_wasi_event_t__bindgen_ty_1__bindgen_ty_1() {
assert_eq!( assert_eq!(
@@ -1186,74 +1144,6 @@ mod test {
); );
} }
#[test]
fn bindgen_test_layout_wasi_ciovec_t() {
assert_eq!(
::std::mem::size_of::<__wasi_ciovec_t>(),
8usize,
concat!("Size of: ", stringify!(__wasi_ciovec_t))
);
assert_eq!(
::std::mem::align_of::<__wasi_ciovec_t>(),
4usize,
concat!("Alignment of ", stringify!(__wasi_ciovec_t))
);
assert_eq!(
unsafe { &(*(::std::ptr::null::<__wasi_ciovec_t>())).buf as *const _ as usize },
0usize,
concat!(
"Offset of field: ",
stringify!(__wasi_ciovec_t),
"::",
stringify!(buf)
)
);
assert_eq!(
unsafe { &(*(::std::ptr::null::<__wasi_ciovec_t>())).buf_len as *const _ as usize },
4usize,
concat!(
"Offset of field: ",
stringify!(__wasi_ciovec_t),
"::",
stringify!(buf_len)
)
);
}
#[test]
fn bindgen_test_layout_wasi_iovec_t() {
assert_eq!(
::std::mem::size_of::<__wasi_iovec_t>(),
8usize,
concat!("Size of: ", stringify!(__wasi_iovec_t))
);
assert_eq!(
::std::mem::align_of::<__wasi_iovec_t>(),
4usize,
concat!("Alignment of ", stringify!(__wasi_iovec_t))
);
assert_eq!(
unsafe { &(*(::std::ptr::null::<__wasi_iovec_t>())).buf as *const _ as usize },
0usize,
concat!(
"Offset of field: ",
stringify!(__wasi_iovec_t),
"::",
stringify!(buf)
)
);
assert_eq!(
unsafe { &(*(::std::ptr::null::<__wasi_iovec_t>())).buf_len as *const _ as usize },
4usize,
concat!(
"Offset of field: ",
stringify!(__wasi_iovec_t),
"::",
stringify!(buf_len)
)
);
}
#[test] #[test]
fn bindgen_test_layout___wasi_subscription_t___wasi_subscription_u___wasi_subscription_u_clock_t( fn bindgen_test_layout___wasi_subscription_t___wasi_subscription_u___wasi_subscription_u_clock_t(
) { ) {
@@ -1505,4 +1395,213 @@ mod test {
) )
); );
} }
#[test]
fn bindgen_test_layout___wasi_filestat_t() {
assert_eq!(
::std::mem::size_of::<__wasi_filestat_t>(),
56usize,
concat!("Size of: ", stringify!(__wasi_filestat_t))
);
assert_eq!(
::std::mem::align_of::<__wasi_filestat_t>(),
8usize,
concat!("Alignment of ", stringify!(__wasi_filestat_t))
);
assert_eq!(
unsafe { &(*(::std::ptr::null::<__wasi_filestat_t>())).st_dev as *const _ as usize },
0usize,
concat!(
"Offset of field: ",
stringify!(__wasi_filestat_t),
"::",
stringify!(st_dev)
)
);
assert_eq!(
unsafe { &(*(::std::ptr::null::<__wasi_filestat_t>())).st_ino as *const _ as usize },
8usize,
concat!(
"Offset of field: ",
stringify!(__wasi_filestat_t),
"::",
stringify!(st_ino)
)
);
assert_eq!(
unsafe {
&(*(::std::ptr::null::<__wasi_filestat_t>())).st_filetype as *const _ as usize
},
16usize,
concat!(
"Offset of field: ",
stringify!(__wasi_filestat_t),
"::",
stringify!(st_filetype)
)
);
assert_eq!(
unsafe { &(*(::std::ptr::null::<__wasi_filestat_t>())).st_nlink as *const _ as usize },
20usize,
concat!(
"Offset of field: ",
stringify!(__wasi_filestat_t),
"::",
stringify!(st_nlink)
)
);
assert_eq!(
unsafe { &(*(::std::ptr::null::<__wasi_filestat_t>())).st_size as *const _ as usize },
24usize,
concat!(
"Offset of field: ",
stringify!(__wasi_filestat_t),
"::",
stringify!(st_size)
)
);
assert_eq!(
unsafe { &(*(::std::ptr::null::<__wasi_filestat_t>())).st_atim as *const _ as usize },
32usize,
concat!(
"Offset of field: ",
stringify!(__wasi_filestat_t),
"::",
stringify!(st_atim)
)
);
assert_eq!(
unsafe { &(*(::std::ptr::null::<__wasi_filestat_t>())).st_mtim as *const _ as usize },
40usize,
concat!(
"Offset of field: ",
stringify!(__wasi_filestat_t),
"::",
stringify!(st_mtim)
)
);
assert_eq!(
unsafe { &(*(::std::ptr::null::<__wasi_filestat_t>())).st_ctim as *const _ as usize },
48usize,
concat!(
"Offset of field: ",
stringify!(__wasi_filestat_t),
"::",
stringify!(st_ctim)
)
);
}
#[test]
fn bindgen_test_layout___wasi_fdstat_t() {
assert_eq!(
::std::mem::size_of::<__wasi_fdstat_t>(),
24usize,
concat!("Size of: ", stringify!(__wasi_fdstat_t))
);
assert_eq!(
::std::mem::align_of::<__wasi_fdstat_t>(),
8usize,
concat!("Alignment of ", stringify!(__wasi_fdstat_t))
);
assert_eq!(
unsafe { &(*(::std::ptr::null::<__wasi_fdstat_t>())).fs_filetype as *const _ as usize },
0usize,
concat!(
"Offset of field: ",
stringify!(__wasi_fdstat_t),
"::",
stringify!(fs_filetype)
)
);
assert_eq!(
unsafe { &(*(::std::ptr::null::<__wasi_fdstat_t>())).fs_flags as *const _ as usize },
2usize,
concat!(
"Offset of field: ",
stringify!(__wasi_fdstat_t),
"::",
stringify!(fs_flags)
)
);
assert_eq!(
unsafe {
&(*(::std::ptr::null::<__wasi_fdstat_t>())).fs_rights_base as *const _ as usize
},
8usize,
concat!(
"Offset of field: ",
stringify!(__wasi_fdstat_t),
"::",
stringify!(fs_rights_base)
)
);
assert_eq!(
unsafe {
&(*(::std::ptr::null::<__wasi_fdstat_t>())).fs_rights_inheriting as *const _
as usize
},
16usize,
concat!(
"Offset of field: ",
stringify!(__wasi_fdstat_t),
"::",
stringify!(fs_rights_inheriting)
)
);
}
#[test]
fn bindgen_test_layout___wasi_dirent_t() {
assert_eq!(
::std::mem::size_of::<__wasi_dirent_t>(),
24usize,
concat!("Size of: ", stringify!(__wasi_dirent_t))
);
assert_eq!(
::std::mem::align_of::<__wasi_dirent_t>(),
8usize,
concat!("Alignment of ", stringify!(__wasi_dirent_t))
);
assert_eq!(
unsafe { &(*(::std::ptr::null::<__wasi_dirent_t>())).d_next as *const _ as usize },
0usize,
concat!(
"Offset of field: ",
stringify!(__wasi_dirent_t),
"::",
stringify!(d_next)
)
);
assert_eq!(
unsafe { &(*(::std::ptr::null::<__wasi_dirent_t>())).d_ino as *const _ as usize },
8usize,
concat!(
"Offset of field: ",
stringify!(__wasi_dirent_t),
"::",
stringify!(d_ino)
)
);
assert_eq!(
unsafe { &(*(::std::ptr::null::<__wasi_dirent_t>())).d_namlen as *const _ as usize },
16usize,
concat!(
"Offset of field: ",
stringify!(__wasi_dirent_t),
"::",
stringify!(d_namlen)
)
);
assert_eq!(
unsafe { &(*(::std::ptr::null::<__wasi_dirent_t>())).d_type as *const _ as usize },
20usize,
concat!(
"Offset of field: ",
stringify!(__wasi_dirent_t),
"::",
stringify!(d_type)
)
);
}
} }

232
src/wasi32.rs Normal file
View File

@@ -0,0 +1,232 @@
//! Types and constants specific to 32-bit wasi. These are similar to the types
//! in the `host` module, but pointers and `usize` values are replaced with
//! `u32`-sized types.
#![allow(non_camel_case_types)]
#![allow(non_snake_case)]
#![allow(dead_code)]
use crate::wasi::*;
// C types
pub type long = i32;
pub type ulong = u32;
// libc types
pub type size_t = ulong;
pub type intptr_t = long;
pub type uintptr_t = ulong;
pub type timer_t = uintptr_t; // *mut ::std::os::raw::c_void
pub type caddr_t = uintptr_t; // *mut i8
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct __wasi_ciovec_t {
pub buf: uintptr_t, // *const ::std::os::raw::c_void
pub buf_len: size_t,
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct __wasi_iovec_t {
pub buf: uintptr_t, // *mut ::std::os::raw::c_void
pub buf_len: size_t,
}
#[repr(C)]
#[derive(Copy, Clone)]
pub struct __wasi_prestat_t {
pub pr_type: __wasi_preopentype_t,
pub u: __wasi_prestat_t___wasi_prestat_u,
}
#[repr(C)]
#[derive(Copy, Clone)]
pub union __wasi_prestat_t___wasi_prestat_u {
pub dir: __wasi_prestat_t___wasi_prestat_u___wasi_prestat_u_dir_t,
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct __wasi_prestat_t___wasi_prestat_u___wasi_prestat_u_dir_t {
pub pr_name_len: size_t,
}
pub const INTPTR_MIN: i32 = -2147483648;
pub const INTPTR_MAX: u32 = 2147483647;
pub const UINTPTR_MAX: u32 = 4294967295;
pub const PTRDIFF_MIN: i32 = -2147483648;
pub const PTRDIFF_MAX: u32 = 2147483647;
pub const SIG_ATOMIC_MIN: i32 = -2147483648;
pub const SIG_ATOMIC_MAX: u32 = 2147483647;
pub const SIZE_MAX: u32 = 4294967295;
#[cfg(test)]
mod test {
use super::*;
#[test]
fn bindgen_test_layout_wasi_ciovec_t() {
assert_eq!(
::std::mem::size_of::<__wasi_ciovec_t>(),
8usize,
concat!("Size of: ", stringify!(__wasi_ciovec_t))
);
assert_eq!(
::std::mem::align_of::<__wasi_ciovec_t>(),
4usize,
concat!("Alignment of ", stringify!(__wasi_ciovec_t))
);
assert_eq!(
unsafe { &(*(::std::ptr::null::<__wasi_ciovec_t>())).buf as *const _ as usize },
0usize,
concat!(
"Offset of field: ",
stringify!(__wasi_ciovec_t),
"::",
stringify!(buf)
)
);
assert_eq!(
unsafe { &(*(::std::ptr::null::<__wasi_ciovec_t>())).buf_len as *const _ as usize },
4usize,
concat!(
"Offset of field: ",
stringify!(__wasi_ciovec_t),
"::",
stringify!(buf_len)
)
);
}
#[test]
fn bindgen_test_layout_wasi_iovec_t() {
assert_eq!(
::std::mem::size_of::<__wasi_iovec_t>(),
8usize,
concat!("Size of: ", stringify!(__wasi_iovec_t))
);
assert_eq!(
::std::mem::align_of::<__wasi_iovec_t>(),
4usize,
concat!("Alignment of ", stringify!(__wasi_iovec_t))
);
assert_eq!(
unsafe { &(*(::std::ptr::null::<__wasi_iovec_t>())).buf as *const _ as usize },
0usize,
concat!(
"Offset of field: ",
stringify!(__wasi_iovec_t),
"::",
stringify!(buf)
)
);
assert_eq!(
unsafe { &(*(::std::ptr::null::<__wasi_iovec_t>())).buf_len as *const _ as usize },
4usize,
concat!(
"Offset of field: ",
stringify!(__wasi_iovec_t),
"::",
stringify!(buf_len)
)
);
}
#[test]
fn bindgen_test_layout___wasi_prestat_t___wasi_prestat_u___wasi_prestat_u_dir_t() {
assert_eq!(
::std::mem::size_of::<__wasi_prestat_t___wasi_prestat_u___wasi_prestat_u_dir_t>(),
4usize,
concat!(
"Size of: ",
stringify!(__wasi_prestat_t___wasi_prestat_u___wasi_prestat_u_dir_t)
)
);
assert_eq!(
::std::mem::align_of::<__wasi_prestat_t___wasi_prestat_u___wasi_prestat_u_dir_t>(),
4usize,
concat!(
"Alignment of ",
stringify!(__wasi_prestat_t___wasi_prestat_u___wasi_prestat_u_dir_t)
)
);
assert_eq!(
unsafe {
&(*(::std::ptr::null::<__wasi_prestat_t___wasi_prestat_u___wasi_prestat_u_dir_t>()))
.pr_name_len as *const _ as usize
},
0usize,
concat!(
"Offset of field: ",
stringify!(__wasi_prestat_t___wasi_prestat_u___wasi_prestat_u_dir_t),
"::",
stringify!(pr_name_len)
)
);
}
#[test]
fn bindgen_test_layout___wasi_prestat_t___wasi_prestat_u() {
assert_eq!(
::std::mem::size_of::<__wasi_prestat_t___wasi_prestat_u>(),
4usize,
concat!("Size of: ", stringify!(__wasi_prestat_t___wasi_prestat_u))
);
assert_eq!(
::std::mem::align_of::<__wasi_prestat_t___wasi_prestat_u>(),
4usize,
concat!(
"Alignment of ",
stringify!(__wasi_prestat_t___wasi_prestat_u)
)
);
assert_eq!(
unsafe {
&(*(::std::ptr::null::<__wasi_prestat_t___wasi_prestat_u>())).dir as *const _
as usize
},
0usize,
concat!(
"Offset of field: ",
stringify!(__wasi_prestat_t___wasi_prestat_u),
"::",
stringify!(dir)
)
);
}
#[test]
fn bindgen_test_layout___wasi_prestat_t() {
assert_eq!(
::std::mem::size_of::<__wasi_prestat_t>(),
8usize,
concat!("Size of: ", stringify!(__wasi_prestat_t))
);
assert_eq!(
::std::mem::align_of::<__wasi_prestat_t>(),
4usize,
concat!("Alignment of ", stringify!(__wasi_prestat_t))
);
assert_eq!(
unsafe { &(*(::std::ptr::null::<__wasi_prestat_t>())).pr_type as *const _ as usize },
0usize,
concat!(
"Offset of field: ",
stringify!(__wasi_prestat_t),
"::",
stringify!(pr_type)
)
);
assert_eq!(
unsafe { &(*(::std::ptr::null::<__wasi_prestat_t>())).u as *const _ as usize },
4usize,
concat!(
"Offset of field: ",
stringify!(__wasi_prestat_t),
"::",
stringify!(u)
)
);
}
}