Add template for Windows impl

This commit is contained in:
Jakub Konka
2019-05-20 11:04:51 +02:00
committed by Dan Gohman
parent 7605584691
commit c3ff3cf075
20 changed files with 575 additions and 339 deletions

View File

@@ -1,7 +1,7 @@
use crate::host; use crate::host;
use crate::sys::dev_null; use crate::sys::dev_null;
use crate::sys::fdmap::{FdEntry, FdMap}; use crate::sys::fdentry::FdEntry;
use failure::{bail, format_err, Error}; use failure::{bail, format_err, Error};
use std::collections::HashMap; use std::collections::HashMap;
@@ -11,7 +11,7 @@ use std::io::{stderr, stdin, stdout};
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
pub struct WasiCtxBuilder { pub struct WasiCtxBuilder {
fds: FdMap, fds: HashMap<host::__wasi_fd_t, FdEntry>,
preopens: HashMap<PathBuf, File>, preopens: HashMap<PathBuf, File>,
args: Vec<CString>, args: Vec<CString>,
env: HashMap<CString, CString>, env: HashMap<CString, CString>,
@@ -21,15 +21,15 @@ impl WasiCtxBuilder {
/// Builder for a new `WasiCtx`. /// Builder for a new `WasiCtx`.
pub fn new() -> Self { pub fn new() -> Self {
let mut builder = Self { let mut builder = Self {
fds: FdMap::new(), fds: HashMap::new(),
preopens: HashMap::new(), preopens: HashMap::new(),
args: vec![], args: vec![],
env: HashMap::new(), env: HashMap::new(),
}; };
builder.fds.insert_fd_entry_at(0, FdEntry::from_file(dev_null())); builder.fds.insert(0, FdEntry::from_file(dev_null()));
builder.fds.insert_fd_entry_at(1, FdEntry::from_file(dev_null())); builder.fds.insert(1, FdEntry::from_file(dev_null()));
builder.fds.insert_fd_entry_at(2, FdEntry::from_file(dev_null())); builder.fds.insert(2, FdEntry::from_file(dev_null()));
builder builder
} }
@@ -62,9 +62,9 @@ impl WasiCtxBuilder {
} }
pub fn inherit_stdio(mut self) -> Self { pub fn inherit_stdio(mut self) -> Self {
self.fds.insert_fd_entry_at(0, FdEntry::duplicate(&stdin())); self.fds.insert(0, FdEntry::duplicate(&stdin()));
self.fds.insert_fd_entry_at(1, FdEntry::duplicate(&stdout())); self.fds.insert(1, FdEntry::duplicate(&stdout()));
self.fds.insert_fd_entry_at(2, FdEntry::duplicate(&stderr())); self.fds.insert(2, FdEntry::duplicate(&stderr()));
self self
} }
@@ -106,15 +106,22 @@ impl WasiCtxBuilder {
} }
pub fn build(mut self) -> Result<WasiCtx, Error> { pub fn build(mut self) -> Result<WasiCtx, Error> {
// startup code starts looking at fd 3 for preopens
let mut preopen_fd = 3;
for (guest_path, dir) in self.preopens { for (guest_path, dir) in self.preopens {
if !dir.metadata()?.is_dir() { if !dir.metadata()?.is_dir() {
bail!("preopened file is not a directory"); bail!("preopened file is not a directory");
} }
while self.fds.contains_key(&preopen_fd) {
preopen_fd = preopen_fd
.checked_add(1)
.ok_or(format_err!("not enough file handles"))?;
}
let mut fe = FdEntry::from_file(dir); let mut fe = FdEntry::from_file(dir);
fe.preopen_path = Some(guest_path); fe.preopen_path = Some(guest_path);
self.fds self.fds.insert(preopen_fd, fe);
.insert_fd_entry(fe) preopen_fd += 1;
.map_err(|_| format_err!("not enough file handles"))?;
} }
let env = self let env = self
@@ -139,7 +146,7 @@ impl WasiCtxBuilder {
#[derive(Debug)] #[derive(Debug)]
pub struct WasiCtx { pub struct WasiCtx {
pub fds: FdMap, pub fds: HashMap<host::__wasi_fd_t, FdEntry>,
pub args: Vec<CString>, pub args: Vec<CString>,
pub env: Vec<CString>, pub env: Vec<CString>,
} }
@@ -167,13 +174,33 @@ impl WasiCtx {
rights_base: host::__wasi_rights_t, rights_base: host::__wasi_rights_t,
rights_inheriting: host::__wasi_rights_t, rights_inheriting: host::__wasi_rights_t,
) -> Result<&FdEntry, host::__wasi_errno_t> { ) -> Result<&FdEntry, host::__wasi_errno_t> {
self.fds.get_fd_entry(fd, rights_base, rights_inheriting) if let Some(fe) = self.fds.get(&fd) {
// validate rights
if !fe.rights_base & rights_base != 0 || !fe.rights_inheriting & rights_inheriting != 0
{
Err(host::__WASI_ENOTCAPABLE)
} else {
Ok(fe)
}
} else {
Err(host::__WASI_EBADF)
}
} }
pub fn insert_fd_entry( pub fn insert_fd_entry(
&mut self, &mut self,
fe: FdEntry, fe: FdEntry,
) -> Result<host::__wasi_fd_t, host::__wasi_errno_t> { ) -> Result<host::__wasi_fd_t, host::__wasi_errno_t> {
self.fds.insert_fd_entry(fe) // never insert where stdio handles usually are
let mut fd = 3;
while self.fds.contains_key(&fd) {
if let Some(next_fd) = fd.checked_add(1) {
fd = next_fd;
} else {
return Err(host::__WASI_EMFILE);
}
}
self.fds.insert(fd, fe);
Ok(fd)
} }
} }

View File

@@ -3,12 +3,13 @@ use crate::ctx::WasiCtx;
use crate::memory::*; use crate::memory::*;
use crate::wasm32; use crate::wasm32;
use crate::sys::hostcalls as hostcalls_impl; // NOTE avoid shadowing `std::convert::From` - cf. rust-lang/rfcs#1311
use cast::From as _0; use cast::From as _0;
use wasi_common_cbindgen::wasi_common_cbindgen; use wasi_common_cbindgen::wasi_common_cbindgen;
pub use crate::sys::hostcalls::*;
#[wasi_common_cbindgen] #[wasi_common_cbindgen]
pub fn args_get( pub fn args_get(
wasi_ctx: &WasiCtx, wasi_ctx: &WasiCtx,
@@ -67,25 +68,6 @@ pub fn args_sizes_get(
wasm32::__WASI_ESUCCESS wasm32::__WASI_ESUCCESS
} }
#[wasi_common_cbindgen]
pub fn clock_res_get(
memory: &mut [u8],
clock_id: wasm32::__wasi_clockid_t,
resolution_ptr: wasm32::uintptr_t,
) -> wasm32::__wasi_errno_t {
hostcalls_impl::clock_res_get(memory, clock_id, resolution_ptr)
}
#[wasi_common_cbindgen]
pub fn clock_time_get(
memory: &mut [u8],
clock_id: wasm32::__wasi_clockid_t,
precision: wasm32::__wasi_timestamp_t,
time_ptr: wasm32::uintptr_t,
) -> wasm32::__wasi_errno_t {
hostcalls_impl::clock_time_get(memory, clock_id, precision, time_ptr)
}
#[wasi_common_cbindgen] #[wasi_common_cbindgen]
pub fn environ_get( pub fn environ_get(
wasi_ctx: &WasiCtx, wasi_ctx: &WasiCtx,
@@ -144,17 +126,6 @@ pub fn environ_sizes_get(
} }
} }
#[wasi_common_cbindgen]
pub fn poll_oneoff(
memory: &mut [u8],
input: wasm32::uintptr_t,
output: wasm32::uintptr_t,
nsubscriptions: wasm32::size_t,
nevents: wasm32::uintptr_t,
) -> wasm32::__wasi_errno_t {
hostcalls_impl::poll_oneoff(memory, input, output, nsubscriptions, nevents)
}
#[wasi_common_cbindgen] #[wasi_common_cbindgen]
pub fn proc_exit(rval: wasm32::__wasi_exitcode_t) -> () { pub fn proc_exit(rval: wasm32::__wasi_exitcode_t) -> () {
// TODO: Rather than call std::process::exit here, we should trigger a // TODO: Rather than call std::process::exit here, we should trigger a
@@ -171,11 +142,6 @@ pub fn proc_raise(
unimplemented!("proc_raise") unimplemented!("proc_raise")
} }
#[wasi_common_cbindgen]
pub fn sched_yield() -> wasm32::__wasi_errno_t {
hostcalls_impl::sched_yield()
}
#[wasi_common_cbindgen] #[wasi_common_cbindgen]
pub fn random_get( pub fn random_get(
memory: &mut [u8], memory: &mut [u8],

View File

@@ -1,7 +0,0 @@
mod fs;
mod misc;
mod sock;
pub use self::fs::*;
pub use self::misc::*;
pub use self::sock::*;

View File

@@ -23,9 +23,9 @@
mod ctx; mod ctx;
mod sys; mod sys;
pub mod memory;
pub mod host; pub mod host;
pub mod hostcalls; pub mod hostcalls;
pub mod memory;
pub mod wasm32; pub mod wasm32;
pub use ctx::{WasiCtx, WasiCtxBuilder}; pub use ctx::{WasiCtx, WasiCtxBuilder};

View File

@@ -1,9 +1,11 @@
//! Functions to go back and forth between WASI types in host and wasm32 representations. //! Functions to go back and forth between WASI types in host and wasm32 representations.
#![allow(unused)]
use crate::{host, wasm32}; use crate::{host, wasm32};
pub use crate::sys::memory::*;
// NOTE avoid shadowing `std::convert::From` - cf. rust-lang/rfcs#1311
use cast::From as _0;
use cast; use cast;
use cast::From as _0;
use std::mem::{align_of, size_of}; use std::mem::{align_of, size_of};
use std::ptr; use std::ptr;
use std::slice; use std::slice;

View File

@@ -1,9 +1,8 @@
use crate::host; use crate::host;
use std::fs::File; use std::fs::File;
use std::os::unix::prelude::{FileTypeExt, FromRawFd, IntoRawFd, RawFd, AsRawFd}; use std::os::unix::prelude::{AsRawFd, FileTypeExt, FromRawFd, IntoRawFd, RawFd};
use std::path::PathBuf; use std::path::PathBuf;
use std::collections::HashMap;
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct FdObject { pub struct FdObject {
@@ -21,11 +20,6 @@ pub struct FdEntry {
pub preopen_path: Option<PathBuf>, pub preopen_path: Option<PathBuf>,
} }
#[derive(Debug)]
pub struct FdMap {
entries: HashMap<host::__wasi_fd_t, FdEntry>,
}
impl Drop for FdObject { impl Drop for FdObject {
fn drop(&mut self) { fn drop(&mut self) {
if self.needs_close { if self.needs_close {
@@ -148,63 +142,3 @@ pub unsafe fn determine_type_rights(
}; };
Ok((ty, rights_base, rights_inheriting)) Ok((ty, rights_base, rights_inheriting))
} }
impl FdMap {
pub fn new() -> Self {
Self {
entries: HashMap::new()
}
}
pub(crate) fn insert_fd_entry_at(&mut self, fd: host::__wasi_fd_t, fe: FdEntry) {
self.entries.insert(fd, fe);
}
pub(crate) fn get(&self, fd: &host::__wasi_fd_t) -> Option<&FdEntry> {
self.entries.get(fd)
}
pub(crate) fn get_mut(&mut self, fd: &host::__wasi_fd_t) -> Option<&mut FdEntry> {
self.entries.get_mut(fd)
}
pub(crate) fn remove(&mut self, fd: &host::__wasi_fd_t) -> Option<FdEntry> {
self.entries.remove(fd)
}
pub fn get_fd_entry(
&self,
fd: host::__wasi_fd_t,
rights_base: host::__wasi_rights_t,
rights_inheriting: host::__wasi_rights_t,
) -> Result<&FdEntry, host::__wasi_errno_t> {
if let Some(fe) = self.entries.get(&fd) {
// validate rights
if !fe.rights_base & rights_base != 0 || !fe.rights_inheriting & rights_inheriting != 0
{
Err(host::__WASI_ENOTCAPABLE)
} else {
Ok(fe)
}
} else {
Err(host::__WASI_EBADF)
}
}
pub fn insert_fd_entry(
&mut self,
fe: FdEntry,
) -> Result<host::__wasi_fd_t, host::__wasi_errno_t> {
// never insert where stdio handles usually are
let mut fd = 3;
while self.entries.contains_key(&fd) {
if let Some(next_fd) = fd.checked_add(1) {
fd = next_fd;
} else {
return Err(host::__WASI_EMFILE);
}
}
self.entries.insert(fd, fe);
Ok(fd)
}
}

View File

@@ -3,26 +3,28 @@
#![allow(non_snake_case)] #![allow(non_snake_case)]
#![allow(dead_code)] #![allow(dead_code)]
use crate::host; use crate::host;
use crate::memory;
use crate::wasm32;
pub fn errno_from_nix(errno: nix::errno::Errno) -> host::__wasi_errno_t { pub fn errno_from_nix(errno: nix::errno::Errno) -> host::__wasi_errno_t {
match errno { match errno {
nix::errno::Errno::EPERM => host::__WASI_EPERM, nix::errno::Errno::EPERM => host::__WASI_EPERM,
nix::errno::Errno::ENOENT => host::__WASI_ENOENT, nix::errno::Errno::ENOENT => host::__WASI_ENOENT,
nix::errno::Errno::ESRCH => host::__WASI_ESRCH, nix::errno::Errno::ESRCH => host::__WASI_ESRCH,
nix::errno::Errno::EINTR => host::__WASI_EINTR, nix::errno::Errno::EINTR => host::__WASI_EINTR,
nix::errno::Errno::EIO => host::__WASI_EIO, nix::errno::Errno::EIO => host::__WASI_EIO,
nix::errno::Errno::ENXIO => host::__WASI_ENXIO, nix::errno::Errno::ENXIO => host::__WASI_ENXIO,
nix::errno::Errno::E2BIG => host::__WASI_E2BIG, nix::errno::Errno::E2BIG => host::__WASI_E2BIG,
nix::errno::Errno::ENOEXEC => host::__WASI_ENOEXEC, nix::errno::Errno::ENOEXEC => host::__WASI_ENOEXEC,
nix::errno::Errno::EBADF => host::__WASI_EBADF, nix::errno::Errno::EBADF => host::__WASI_EBADF,
nix::errno::Errno::ECHILD => host::__WASI_ECHILD, nix::errno::Errno::ECHILD => host::__WASI_ECHILD,
nix::errno::Errno::EAGAIN => host::__WASI_EAGAIN, nix::errno::Errno::EAGAIN => host::__WASI_EAGAIN,
nix::errno::Errno::ENOMEM => host::__WASI_ENOMEM, nix::errno::Errno::ENOMEM => host::__WASI_ENOMEM,
nix::errno::Errno::EACCES => host::__WASI_EACCES, nix::errno::Errno::EACCES => host::__WASI_EACCES,
nix::errno::Errno::EFAULT => host::__WASI_EFAULT, nix::errno::Errno::EFAULT => host::__WASI_EFAULT,
nix::errno::Errno::EBUSY => host::__WASI_EBUSY, nix::errno::Errno::EBUSY => host::__WASI_EBUSY,
nix::errno::Errno::EEXIST => host::__WASI_EEXIST, nix::errno::Errno::EEXIST => host::__WASI_EEXIST,
nix::errno::Errno::EXDEV => host::__WASI_EXDEV, nix::errno::Errno::EXDEV => host::__WASI_EXDEV,
nix::errno::Errno::ENODEV => host::__WASI_ENODEV, nix::errno::Errno::ENODEV => host::__WASI_ENODEV,
nix::errno::Errno::ENOTDIR => host::__WASI_ENOTDIR, nix::errno::Errno::ENOTDIR => host::__WASI_ENOTDIR,
nix::errno::Errno::EISDIR => host::__WASI_EISDIR, nix::errno::Errno::EISDIR => host::__WASI_EISDIR,
@@ -31,60 +33,62 @@ pub fn errno_from_nix(errno: nix::errno::Errno) -> host::__wasi_errno_t {
nix::errno::Errno::EMFILE => host::__WASI_EMFILE, nix::errno::Errno::EMFILE => host::__WASI_EMFILE,
nix::errno::Errno::ENOTTY => host::__WASI_ENOTTY, nix::errno::Errno::ENOTTY => host::__WASI_ENOTTY,
nix::errno::Errno::ETXTBSY => host::__WASI_ETXTBSY, nix::errno::Errno::ETXTBSY => host::__WASI_ETXTBSY,
nix::errno::Errno::EFBIG => host::__WASI_EFBIG, nix::errno::Errno::EFBIG => host::__WASI_EFBIG,
nix::errno::Errno::ENOSPC => host::__WASI_ENOSPC, nix::errno::Errno::ENOSPC => host::__WASI_ENOSPC,
nix::errno::Errno::ESPIPE => host::__WASI_ESPIPE, nix::errno::Errno::ESPIPE => host::__WASI_ESPIPE,
nix::errno::Errno::EROFS => host::__WASI_EROFS, nix::errno::Errno::EROFS => host::__WASI_EROFS,
nix::errno::Errno::EMLINK => host::__WASI_EMLINK, nix::errno::Errno::EMLINK => host::__WASI_EMLINK,
nix::errno::Errno::EPIPE => host::__WASI_EPIPE, nix::errno::Errno::EPIPE => host::__WASI_EPIPE,
nix::errno::Errno::EDOM => host::__WASI_EDOM, nix::errno::Errno::EDOM => host::__WASI_EDOM,
nix::errno::Errno::ERANGE => host::__WASI_ERANGE, nix::errno::Errno::ERANGE => host::__WASI_ERANGE,
nix::errno::Errno::EDEADLK => host::__WASI_EDEADLK, nix::errno::Errno::EDEADLK => host::__WASI_EDEADLK,
nix::errno::Errno::ENAMETOOLONG => host::__WASI_ENAMETOOLONG, nix::errno::Errno::ENAMETOOLONG => host::__WASI_ENAMETOOLONG,
nix::errno::Errno::ENOLCK => host::__WASI_ENOLCK, nix::errno::Errno::ENOLCK => host::__WASI_ENOLCK,
nix::errno::Errno::ENOSYS => host::__WASI_ENOSYS, nix::errno::Errno::ENOSYS => host::__WASI_ENOSYS,
nix::errno::Errno::ENOTEMPTY => host::__WASI_ENOTEMPTY, nix::errno::Errno::ENOTEMPTY => host::__WASI_ENOTEMPTY,
nix::errno::Errno::ELOOP => host::__WASI_ELOOP, nix::errno::Errno::ELOOP => host::__WASI_ELOOP,
nix::errno::Errno::ENOMSG => host::__WASI_ENOMSG, nix::errno::Errno::ENOMSG => host::__WASI_ENOMSG,
nix::errno::Errno::EIDRM => host::__WASI_EIDRM, nix::errno::Errno::EIDRM => host::__WASI_EIDRM,
nix::errno::Errno::ENOLINK => host::__WASI_ENOLINK, nix::errno::Errno::ENOLINK => host::__WASI_ENOLINK,
nix::errno::Errno::EPROTO => host::__WASI_EPROTO, nix::errno::Errno::EPROTO => host::__WASI_EPROTO,
nix::errno::Errno::EMULTIHOP => host::__WASI_EMULTIHOP, nix::errno::Errno::EMULTIHOP => host::__WASI_EMULTIHOP,
nix::errno::Errno::EBADMSG => host::__WASI_EBADMSG, nix::errno::Errno::EBADMSG => host::__WASI_EBADMSG,
nix::errno::Errno::EOVERFLOW => host::__WASI_EOVERFLOW, nix::errno::Errno::EOVERFLOW => host::__WASI_EOVERFLOW,
nix::errno::Errno::EILSEQ => host::__WASI_EILSEQ, nix::errno::Errno::EILSEQ => host::__WASI_EILSEQ,
nix::errno::Errno::ENOTSOCK => host::__WASI_ENOTSOCK, nix::errno::Errno::ENOTSOCK => host::__WASI_ENOTSOCK,
nix::errno::Errno::EDESTADDRREQ => host::__WASI_EDESTADDRREQ, nix::errno::Errno::EDESTADDRREQ => host::__WASI_EDESTADDRREQ,
nix::errno::Errno::EMSGSIZE => host::__WASI_EMSGSIZE, nix::errno::Errno::EMSGSIZE => host::__WASI_EMSGSIZE,
nix::errno::Errno::EPROTOTYPE => host::__WASI_EPROTOTYPE, nix::errno::Errno::EPROTOTYPE => host::__WASI_EPROTOTYPE,
nix::errno::Errno::ENOPROTOOPT => host::__WASI_ENOPROTOOPT, nix::errno::Errno::ENOPROTOOPT => host::__WASI_ENOPROTOOPT,
nix::errno::Errno::EPROTONOSUPPORT => host::__WASI_EPROTONOSUPPORT, nix::errno::Errno::EPROTONOSUPPORT => host::__WASI_EPROTONOSUPPORT,
nix::errno::Errno::EAFNOSUPPORT => host::__WASI_EAFNOSUPPORT, nix::errno::Errno::EAFNOSUPPORT => host::__WASI_EAFNOSUPPORT,
nix::errno::Errno::EADDRINUSE => host::__WASI_EADDRINUSE, nix::errno::Errno::EADDRINUSE => host::__WASI_EADDRINUSE,
nix::errno::Errno::EADDRNOTAVAIL => host::__WASI_EADDRNOTAVAIL, nix::errno::Errno::EADDRNOTAVAIL => host::__WASI_EADDRNOTAVAIL,
nix::errno::Errno::ENETDOWN => host::__WASI_ENETDOWN, nix::errno::Errno::ENETDOWN => host::__WASI_ENETDOWN,
nix::errno::Errno::ENETUNREACH => host::__WASI_ENETUNREACH, nix::errno::Errno::ENETUNREACH => host::__WASI_ENETUNREACH,
nix::errno::Errno::ENETRESET => host::__WASI_ENETRESET, nix::errno::Errno::ENETRESET => host::__WASI_ENETRESET,
nix::errno::Errno::ECONNABORTED => host::__WASI_ECONNABORTED, nix::errno::Errno::ECONNABORTED => host::__WASI_ECONNABORTED,
nix::errno::Errno::ECONNRESET => host::__WASI_ECONNRESET, nix::errno::Errno::ECONNRESET => host::__WASI_ECONNRESET,
nix::errno::Errno::ENOBUFS => host::__WASI_ENOBUFS, nix::errno::Errno::ENOBUFS => host::__WASI_ENOBUFS,
nix::errno::Errno::EISCONN => host::__WASI_EISCONN, nix::errno::Errno::EISCONN => host::__WASI_EISCONN,
nix::errno::Errno::ENOTCONN => host::__WASI_ENOTCONN, nix::errno::Errno::ENOTCONN => host::__WASI_ENOTCONN,
nix::errno::Errno::ETIMEDOUT => host::__WASI_ETIMEDOUT, nix::errno::Errno::ETIMEDOUT => host::__WASI_ETIMEDOUT,
nix::errno::Errno::ECONNREFUSED => host::__WASI_ECONNREFUSED, nix::errno::Errno::ECONNREFUSED => host::__WASI_ECONNREFUSED,
nix::errno::Errno::EHOSTUNREACH => host::__WASI_EHOSTUNREACH, nix::errno::Errno::EHOSTUNREACH => host::__WASI_EHOSTUNREACH,
nix::errno::Errno::EALREADY => host::__WASI_EALREADY, nix::errno::Errno::EALREADY => host::__WASI_EALREADY,
nix::errno::Errno::EINPROGRESS => host::__WASI_EINPROGRESS, nix::errno::Errno::EINPROGRESS => host::__WASI_EINPROGRESS,
nix::errno::Errno::ESTALE => host::__WASI_ESTALE, nix::errno::Errno::ESTALE => host::__WASI_ESTALE,
nix::errno::Errno::EDQUOT => host::__WASI_EDQUOT, nix::errno::Errno::EDQUOT => host::__WASI_EDQUOT,
nix::errno::Errno::ECANCELED => host::__WASI_ECANCELED, nix::errno::Errno::ECANCELED => host::__WASI_ECANCELED,
nix::errno::Errno::EOWNERDEAD => host::__WASI_EOWNERDEAD, nix::errno::Errno::EOWNERDEAD => host::__WASI_EOWNERDEAD,
nix::errno::Errno::ENOTRECOVERABLE => host::__WASI_ENOTRECOVERABLE, nix::errno::Errno::ENOTRECOVERABLE => host::__WASI_ENOTRECOVERABLE,
_ => host::__WASI_ENOSYS, _ => host::__WASI_ENOSYS,
} }
} }
pub unsafe fn ciovec_to_nix<'a>(ciovec: &'a host::__wasi_ciovec_t) -> nix::sys::uio::IoVec<&'a [u8]> { pub unsafe fn ciovec_to_nix<'a>(
ciovec: &'a host::__wasi_ciovec_t,
) -> nix::sys::uio::IoVec<&'a [u8]> {
let slice = std::slice::from_raw_parts(ciovec.buf as *const u8, ciovec.buf_len); let slice = std::slice::from_raw_parts(ciovec.buf as *const u8, ciovec.buf_len);
nix::sys::uio::IoVec::from_slice(slice) nix::sys::uio::IoVec::from_slice(slice)
} }
@@ -231,10 +235,40 @@ pub fn filestat_from_nix(filestat: nix::sys::stat::FileStat) -> host::__wasi_fil
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 host::__wasi_linkcount_t,
st_size: filestat.st_size as host::__wasi_filesize_t, st_size: filestat.st_size as host::__wasi_filesize_t,
st_atim: filestat.st_atime as host::__wasi_timestamp_t, st_atim: filestat.st_atime as host::__wasi_timestamp_t,
st_ctim: filestat.st_ctime as host::__wasi_timestamp_t, st_ctim: filestat.st_ctime as host::__wasi_timestamp_t,
st_mtim: filestat.st_mtime as host::__wasi_timestamp_t, st_mtim: filestat.st_mtime as host::__wasi_timestamp_t,
st_filetype: filetype_from_nix(filetype), st_filetype: filetype_from_nix(filetype),
} }
} }
#[cfg(target_os = "linux")]
pub fn dirent_from_host(
host_entry: &nix::libc::dirent,
) -> Result<wasm32::__wasi_dirent_t, host::__wasi_errno_t> {
let mut entry = unsafe { std::mem::zeroed::<wasm32::__wasi_dirent_t>() };
let d_namlen = unsafe { std::ffi::CStr::from_ptr(host_entry.d_name.as_ptr()) }
.to_bytes()
.len();
if d_namlen > u32::max_value() as usize {
return Err(host::__WASI_EIO);
}
entry.d_ino = memory::enc_inode(host_entry.d_ino);
entry.d_next = memory::enc_dircookie(host_entry.d_off as u64);
entry.d_namlen = memory::enc_u32(d_namlen as u32);
entry.d_type = memory::enc_filetype(host_entry.d_type);
Ok(entry)
}
#[cfg(not(target_os = "linux"))]
pub fn dirent_from_host(
host_entry: &nix::libc::dirent,
) -> Result<wasm32::__wasi_dirent_t, host::__wasi_errno_t> {
let mut entry = unsafe { std::mem::zeroed::<wasm32::__wasi_dirent_t>() };
entry.d_ino = memory::enc_inode(host_entry.d_ino);
entry.d_next = memory::enc_dircookie(host_entry.d_seekoff);
entry.d_namlen = memory::enc_u32(u32::from(host_entry.d_namlen));
entry.d_type = memory::enc_filetype(host_entry.d_type);
Ok(entry)
}

View File

@@ -1,18 +1,19 @@
#![allow(non_camel_case_types)] #![allow(non_camel_case_types)]
#![allow(unused_unsafe)] #![allow(unused_unsafe)]
use crate::sys::fdmap::{determine_type_rights, FdEntry}; use super::fdentry::{determine_type_rights, FdEntry};
use crate::sys::host as host_impl; use super::fs_helpers::*;
use super::host_impl;
use crate::ctx::WasiCtx; use crate::ctx::WasiCtx;
use crate::memory::*; use crate::memory::*;
use crate::{host, wasm32}; use crate::{host, wasm32};
use super::fs_helpers::*;
use nix::libc::{self, c_long, c_void, off_t}; use nix::libc::{self, c_long, c_void, off_t};
use std::ffi::OsStr; use std::ffi::OsStr;
use std::os::unix::prelude::{FromRawFd, OsStrExt}; use std::os::unix::prelude::{FromRawFd, OsStrExt};
use wasi_common_cbindgen::wasi_common_cbindgen;
#[wasi_common_cbindgen]
pub fn fd_close(wasi_ctx: &mut WasiCtx, fd: wasm32::__wasi_fd_t) -> wasm32::__wasi_errno_t { pub fn fd_close(wasi_ctx: &mut WasiCtx, fd: wasm32::__wasi_fd_t) -> wasm32::__wasi_errno_t {
let fd = dec_fd(fd); let fd = dec_fd(fd);
if let Some(fdent) = wasi_ctx.fds.get(&fd) { if let Some(fdent) = wasi_ctx.fds.get(&fd) {
@@ -32,6 +33,7 @@ pub fn fd_close(wasi_ctx: &mut WasiCtx, fd: wasm32::__wasi_fd_t) -> wasm32::__wa
} }
} }
#[wasi_common_cbindgen]
pub fn fd_datasync(wasi_ctx: &WasiCtx, fd: wasm32::__wasi_fd_t) -> wasm32::__wasi_errno_t { pub fn fd_datasync(wasi_ctx: &WasiCtx, fd: wasm32::__wasi_fd_t) -> wasm32::__wasi_errno_t {
let host_fd = dec_fd(fd); let host_fd = dec_fd(fd);
let rights = host::__WASI_RIGHT_FD_DATASYNC; let rights = host::__WASI_RIGHT_FD_DATASYNC;
@@ -57,6 +59,7 @@ pub fn fd_datasync(wasi_ctx: &WasiCtx, fd: wasm32::__wasi_fd_t) -> wasm32::__was
wasm32::__WASI_ESUCCESS wasm32::__WASI_ESUCCESS
} }
#[wasi_common_cbindgen]
pub fn fd_pread( pub fn fd_pread(
wasi_ctx: &WasiCtx, wasi_ctx: &WasiCtx,
memory: &mut [u8], memory: &mut [u8],
@@ -106,6 +109,7 @@ pub fn fd_pread(
.unwrap_or_else(|e| e) .unwrap_or_else(|e| e)
} }
#[wasi_common_cbindgen]
pub fn fd_pwrite( pub fn fd_pwrite(
wasi_ctx: &WasiCtx, wasi_ctx: &WasiCtx,
memory: &mut [u8], memory: &mut [u8],
@@ -147,6 +151,7 @@ pub fn fd_pwrite(
.unwrap_or_else(|e| e) .unwrap_or_else(|e| e)
} }
#[wasi_common_cbindgen]
pub fn fd_read( pub fn fd_read(
wasi_ctx: &mut WasiCtx, wasi_ctx: &mut WasiCtx,
memory: &mut [u8], memory: &mut [u8],
@@ -189,6 +194,7 @@ pub fn fd_read(
.unwrap_or_else(|e| e) .unwrap_or_else(|e| e)
} }
#[wasi_common_cbindgen]
pub fn fd_renumber( pub fn fd_renumber(
wasi_ctx: &mut WasiCtx, wasi_ctx: &mut WasiCtx,
from: wasm32::__wasi_fd_t, from: wasm32::__wasi_fd_t,
@@ -213,6 +219,7 @@ pub fn fd_renumber(
wasm32::__WASI_ESUCCESS wasm32::__WASI_ESUCCESS
} }
#[wasi_common_cbindgen]
pub fn fd_seek( pub fn fd_seek(
wasi_ctx: &WasiCtx, wasi_ctx: &WasiCtx,
memory: &mut [u8], memory: &mut [u8],
@@ -253,6 +260,7 @@ pub fn fd_seek(
.unwrap_or_else(|e| e) .unwrap_or_else(|e| e)
} }
#[wasi_common_cbindgen]
pub fn fd_tell( pub fn fd_tell(
wasi_ctx: &WasiCtx, wasi_ctx: &WasiCtx,
memory: &mut [u8], memory: &mut [u8],
@@ -279,6 +287,7 @@ pub fn fd_tell(
.unwrap_or_else(|e| e) .unwrap_or_else(|e| e)
} }
#[wasi_common_cbindgen]
pub fn fd_fdstat_get( pub fn fd_fdstat_get(
wasi_ctx: &WasiCtx, wasi_ctx: &WasiCtx,
memory: &mut [u8], memory: &mut [u8],
@@ -313,6 +322,7 @@ pub fn fd_fdstat_get(
errno errno
} }
#[wasi_common_cbindgen]
pub fn fd_fdstat_set_flags( pub fn fd_fdstat_set_flags(
wasi_ctx: &WasiCtx, wasi_ctx: &WasiCtx,
fd: wasm32::__wasi_fd_t, fd: wasm32::__wasi_fd_t,
@@ -332,6 +342,7 @@ pub fn fd_fdstat_set_flags(
} }
} }
#[wasi_common_cbindgen]
pub fn fd_fdstat_set_rights( pub fn fd_fdstat_set_rights(
wasi_ctx: &mut WasiCtx, wasi_ctx: &mut WasiCtx,
fd: wasm32::__wasi_fd_t, fd: wasm32::__wasi_fd_t,
@@ -354,6 +365,7 @@ pub fn fd_fdstat_set_rights(
wasm32::__WASI_ESUCCESS wasm32::__WASI_ESUCCESS
} }
#[wasi_common_cbindgen]
pub fn fd_sync(wasi_ctx: &WasiCtx, fd: wasm32::__wasi_fd_t) -> wasm32::__wasi_errno_t { pub fn fd_sync(wasi_ctx: &WasiCtx, fd: wasm32::__wasi_fd_t) -> wasm32::__wasi_errno_t {
let host_fd = dec_fd(fd); let host_fd = dec_fd(fd);
let rights = host::__WASI_RIGHT_FD_SYNC; let rights = host::__WASI_RIGHT_FD_SYNC;
@@ -368,6 +380,7 @@ pub fn fd_sync(wasi_ctx: &WasiCtx, fd: wasm32::__wasi_fd_t) -> wasm32::__wasi_er
wasm32::__WASI_ESUCCESS wasm32::__WASI_ESUCCESS
} }
#[wasi_common_cbindgen]
pub fn fd_write( pub fn fd_write(
wasi_ctx: &WasiCtx, wasi_ctx: &WasiCtx,
memory: &mut [u8], memory: &mut [u8],
@@ -404,6 +417,7 @@ pub fn fd_write(
.unwrap_or_else(|e| e) .unwrap_or_else(|e| e)
} }
#[wasi_common_cbindgen]
pub fn fd_advise( pub fn fd_advise(
wasi_ctx: &WasiCtx, wasi_ctx: &WasiCtx,
fd: wasm32::__wasi_fd_t, fd: wasm32::__wasi_fd_t,
@@ -462,6 +476,7 @@ pub fn fd_advise(
wasm32::__WASI_ESUCCESS wasm32::__WASI_ESUCCESS
} }
#[wasi_common_cbindgen]
pub fn fd_allocate( pub fn fd_allocate(
wasi_ctx: &WasiCtx, wasi_ctx: &WasiCtx,
fd: wasm32::__wasi_fd_t, fd: wasm32::__wasi_fd_t,
@@ -514,6 +529,7 @@ pub fn fd_allocate(
wasm32::__WASI_ESUCCESS wasm32::__WASI_ESUCCESS
} }
#[wasi_common_cbindgen]
pub fn path_create_directory( pub fn path_create_directory(
wasi_ctx: &WasiCtx, wasi_ctx: &WasiCtx,
memory: &mut [u8], memory: &mut [u8],
@@ -552,6 +568,7 @@ pub fn path_create_directory(
} }
} }
#[wasi_common_cbindgen]
pub fn path_link( pub fn path_link(
wasi_ctx: &WasiCtx, wasi_ctx: &WasiCtx,
memory: &mut [u8], memory: &mut [u8],
@@ -613,6 +630,7 @@ pub fn path_link(
wasm32::__WASI_ESUCCESS wasm32::__WASI_ESUCCESS
} }
#[wasi_common_cbindgen]
pub fn path_open( pub fn path_open(
wasi_ctx: &mut WasiCtx, wasi_ctx: &mut WasiCtx,
memory: &mut [u8], memory: &mut [u8],
@@ -770,6 +788,7 @@ pub fn path_open(
.unwrap_or_else(|e| e) .unwrap_or_else(|e| e)
} }
#[wasi_common_cbindgen]
pub fn fd_readdir( pub fn fd_readdir(
wasi_ctx: &WasiCtx, wasi_ctx: &WasiCtx,
memory: &mut [u8], memory: &mut [u8],
@@ -817,10 +836,11 @@ pub fn fd_readdir(
if host_entry.is_null() { if host_entry.is_null() {
break; break;
} }
let entry: wasm32::__wasi_dirent_t = match dirent_from_host(&unsafe { *host_entry }) { let entry: wasm32::__wasi_dirent_t =
Ok(entry) => entry, match host_impl::dirent_from_host(&unsafe { *host_entry }) {
Err(e) => return enc_errno(e), Ok(entry) => entry,
}; Err(e) => return enc_errno(e),
};
let name_len = entry.d_namlen as usize; let name_len = entry.d_namlen as usize;
let required_space = std::mem::size_of_val(&entry) + name_len; let required_space = std::mem::size_of_val(&entry) + name_len;
if required_space > left { if required_space > left {
@@ -849,6 +869,7 @@ pub fn fd_readdir(
.unwrap_or_else(|e| e) .unwrap_or_else(|e| e)
} }
#[wasi_common_cbindgen]
pub fn path_readlink( pub fn path_readlink(
wasi_ctx: &WasiCtx, wasi_ctx: &WasiCtx,
memory: &mut [u8], memory: &mut [u8],
@@ -892,6 +913,7 @@ pub fn path_readlink(
wasm32::__WASI_ESUCCESS wasm32::__WASI_ESUCCESS
} }
#[wasi_common_cbindgen]
pub fn path_rename( pub fn path_rename(
wasi_ctx: &WasiCtx, wasi_ctx: &WasiCtx,
memory: &mut [u8], memory: &mut [u8],
@@ -948,6 +970,7 @@ pub fn path_rename(
wasm32::__WASI_ESUCCESS wasm32::__WASI_ESUCCESS
} }
#[wasi_common_cbindgen]
pub fn fd_filestat_get( pub fn fd_filestat_get(
wasi_ctx: &WasiCtx, wasi_ctx: &WasiCtx,
memory: &mut [u8], memory: &mut [u8],
@@ -974,6 +997,7 @@ pub fn fd_filestat_get(
errno errno
} }
#[wasi_common_cbindgen]
pub fn fd_filestat_set_times( pub fn fd_filestat_set_times(
wasi_ctx: &WasiCtx, wasi_ctx: &WasiCtx,
fd: wasm32::__wasi_fd_t, fd: wasm32::__wasi_fd_t,
@@ -1030,6 +1054,7 @@ pub fn fd_filestat_set_times(
wasm32::__WASI_ESUCCESS wasm32::__WASI_ESUCCESS
} }
#[wasi_common_cbindgen]
pub fn fd_filestat_set_size( pub fn fd_filestat_set_size(
wasi_ctx: &WasiCtx, wasi_ctx: &WasiCtx,
fd: wasm32::__wasi_fd_t, fd: wasm32::__wasi_fd_t,
@@ -1053,6 +1078,7 @@ pub fn fd_filestat_set_size(
wasm32::__WASI_ESUCCESS wasm32::__WASI_ESUCCESS
} }
#[wasi_common_cbindgen]
pub fn path_filestat_get( pub fn path_filestat_get(
wasi_ctx: &WasiCtx, wasi_ctx: &WasiCtx,
memory: &mut [u8], memory: &mut [u8],
@@ -1098,6 +1124,7 @@ pub fn path_filestat_get(
} }
} }
#[wasi_common_cbindgen]
pub fn path_filestat_set_times( pub fn path_filestat_set_times(
wasi_ctx: &WasiCtx, wasi_ctx: &WasiCtx,
memory: &mut [u8], memory: &mut [u8],
@@ -1171,6 +1198,7 @@ pub fn path_filestat_set_times(
wasm32::__WASI_ESUCCESS wasm32::__WASI_ESUCCESS
} }
#[wasi_common_cbindgen]
pub fn path_symlink( pub fn path_symlink(
wasi_ctx: &WasiCtx, wasi_ctx: &WasiCtx,
memory: &mut [u8], memory: &mut [u8],
@@ -1211,6 +1239,7 @@ pub fn path_symlink(
wasm32::__WASI_ESUCCESS wasm32::__WASI_ESUCCESS
} }
#[wasi_common_cbindgen]
pub fn path_unlink_file( pub fn path_unlink_file(
wasi_ctx: &WasiCtx, wasi_ctx: &WasiCtx,
memory: &mut [u8], memory: &mut [u8],
@@ -1249,6 +1278,7 @@ pub fn path_unlink_file(
} }
} }
#[wasi_common_cbindgen]
pub fn path_remove_directory( pub fn path_remove_directory(
wasi_ctx: &WasiCtx, wasi_ctx: &WasiCtx,
memory: &mut [u8], memory: &mut [u8],
@@ -1280,6 +1310,7 @@ pub fn path_remove_directory(
} }
} }
#[wasi_common_cbindgen]
pub fn fd_prestat_get( pub fn fd_prestat_get(
wasi_ctx: &WasiCtx, wasi_ctx: &WasiCtx,
memory: &mut [u8], memory: &mut [u8],
@@ -1316,6 +1347,7 @@ pub fn fd_prestat_get(
} }
} }
#[wasi_common_cbindgen]
pub fn fd_prestat_dir_name( pub fn fd_prestat_dir_name(
wasi_ctx: &WasiCtx, wasi_ctx: &WasiCtx,
memory: &mut [u8], memory: &mut [u8],

View File

@@ -1,9 +1,9 @@
#![allow(non_camel_case_types)] #![allow(non_camel_case_types)]
#![allow(unused_unsafe)] #![allow(unused_unsafe)]
use super::host_impl;
use crate::ctx::WasiCtx; use crate::ctx::WasiCtx;
use crate::host; use crate::host;
use crate::sys::host as host_impl;
use nix::libc::{self, c_long}; use nix::libc::{self, c_long};
use std::ffi::{OsStr, OsString}; use std::ffi::{OsStr, OsString};

View File

@@ -1,15 +1,17 @@
#![allow(non_camel_case_types)] #![allow(non_camel_case_types)]
#![allow(unused_unsafe)] #![allow(unused_unsafe)]
use super::host_impl;
use crate::memory::*; use crate::memory::*;
use crate::{host, wasm32}; use crate::{host, wasm32};
use crate::sys::host as host_impl;
use nix::convert_ioctl_res; use nix::convert_ioctl_res;
use nix::libc::{self, c_int}; use nix::libc::{self, c_int};
use std::cmp; use std::cmp;
use std::time::SystemTime; use std::time::SystemTime;
use wasi_common_cbindgen::wasi_common_cbindgen;
#[wasi_common_cbindgen]
pub fn clock_res_get( pub fn clock_res_get(
memory: &mut [u8], memory: &mut [u8],
clock_id: wasm32::__wasi_clockid_t, clock_id: wasm32::__wasi_clockid_t,
@@ -49,6 +51,7 @@ pub fn clock_res_get(
}) })
} }
#[wasi_common_cbindgen]
pub fn clock_time_get( pub fn clock_time_get(
memory: &mut [u8], memory: &mut [u8],
clock_id: wasm32::__wasi_clockid_t, clock_id: wasm32::__wasi_clockid_t,
@@ -85,6 +88,7 @@ pub fn clock_time_get(
}) })
} }
#[wasi_common_cbindgen]
pub fn poll_oneoff( pub fn poll_oneoff(
memory: &mut [u8], memory: &mut [u8],
input: wasm32::uintptr_t, input: wasm32::uintptr_t,
@@ -176,6 +180,7 @@ pub fn poll_oneoff(
wasm32::__WASI_ESUCCESS wasm32::__WASI_ESUCCESS
} }
#[wasi_common_cbindgen]
pub fn sched_yield() -> wasm32::__wasi_errno_t { pub fn sched_yield() -> wasm32::__wasi_errno_t {
unsafe { libc::sched_yield() }; unsafe { libc::sched_yield() };
wasm32::__WASI_ESUCCESS wasm32::__WASI_ESUCCESS

View File

@@ -1,10 +1,13 @@
//! Hostcalls that implement //! Unix-specific hostcalls that implement
//! [WASI](https://github.com/CraneStation/wasmtime-wasi/blob/wasi/docs/WASI-overview.md). //! [WASI](https://github.com/CraneStation/wasmtime-wasi/blob/wasi/docs/WASI-overview.md).
mod fs; mod fs;
mod fs_helpers; mod fs_helpers;
mod misc; mod misc;
mod sock; mod sock;
use super::fdentry;
use super::host_impl;
pub use self::fs::*; pub use self::fs::*;
pub use self::misc::*; pub use self::misc::*;
pub use self::sock::*; pub use self::sock::*;

View File

@@ -6,6 +6,7 @@ use crate::ctx::WasiCtx;
use crate::wasm32; use crate::wasm32;
use wasi_common_cbindgen::wasi_common_cbindgen; use wasi_common_cbindgen::wasi_common_cbindgen;
#[wasi_common_cbindgen]
pub fn sock_recv( pub fn sock_recv(
wasi_ctx: &WasiCtx, wasi_ctx: &WasiCtx,
memory: &mut [u8], memory: &mut [u8],
@@ -19,6 +20,7 @@ pub fn sock_recv(
unimplemented!("sock_recv") unimplemented!("sock_recv")
} }
#[wasi_common_cbindgen]
pub fn sock_send( pub fn sock_send(
wasi_ctx: &WasiCtx, wasi_ctx: &WasiCtx,
memory: &mut [u8], memory: &mut [u8],
@@ -31,6 +33,7 @@ pub fn sock_send(
unimplemented!("sock_send") unimplemented!("sock_send")
} }
#[wasi_common_cbindgen]
pub fn sock_shutdown( pub fn sock_shutdown(
wasi_ctx: &WasiCtx, wasi_ctx: &WasiCtx,
memory: &mut [u8], memory: &mut [u8],
@@ -38,4 +41,4 @@ pub fn sock_shutdown(
how: wasm32::__wasi_sdflags_t, how: wasm32::__wasi_sdflags_t,
) -> wasm32::__wasi_errno_t { ) -> wasm32::__wasi_errno_t {
unimplemented!("sock_shutdown") unimplemented!("sock_shutdown")
} }

View File

@@ -1,41 +1,6 @@
pub mod host; pub mod fdentry;
mod host_impl;
pub mod hostcalls; pub mod hostcalls;
pub mod fdmap;
pub mod memory {
use crate::{host, wasm32};
use crate::memory::*;
#[cfg(target_os = "linux")]
pub fn dirent_from_host(
host_entry: &nix::libc::dirent,
) -> Result<wasm32::__wasi_dirent_t, host::__wasi_errno_t> {
let mut entry = unsafe { std::mem::zeroed::<wasm32::__wasi_dirent_t>() };
let d_namlen = unsafe { std::ffi::CStr::from_ptr(host_entry.d_name.as_ptr()) }
.to_bytes()
.len();
if d_namlen > u32::max_value() as usize {
return Err(host::__WASI_EIO);
}
entry.d_ino = enc_inode(host_entry.d_ino);
entry.d_next = enc_dircookie(host_entry.d_off as u64);
entry.d_namlen = enc_u32(d_namlen as u32);
entry.d_type = enc_filetype(host_entry.d_type);
Ok(entry)
}
#[cfg(not(target_os = "linux"))]
pub fn dirent_from_host(
host_entry: &nix::libc::dirent,
) -> Result<wasm32::__wasi_dirent_t, host::__wasi_errno_t> {
let mut entry = unsafe { std::mem::zeroed::<wasm32::__wasi_dirent_t>() };
entry.d_ino = enc_inode(host_entry.d_ino);
entry.d_next = enc_dircookie(host_entry.d_seekoff);
entry.d_namlen = enc_u32(u32::from(host_entry.d_namlen));
entry.d_type = enc_filetype(host_entry.d_type);
Ok(entry)
}
}
pub fn dev_null() -> std::fs::File { pub fn dev_null() -> std::fs::File {
std::fs::File::open("/dev/null").expect("failed to open /dev/null") std::fs::File::open("/dev/null").expect("failed to open /dev/null")

View File

@@ -0,0 +1,89 @@
use crate::host;
use std::fs::File;
use std::os::windows::prelude::{AsRawHandle, FromRawHandle, IntoRawHandle, RawHandle};
use std::path::PathBuf;
use winapi::shared::minwindef::FALSE;
use winapi::um::handleapi::DuplicateHandle;
use winapi::um::processthreadsapi::GetCurrentProcess;
use winapi::um::winnt::DUPLICATE_SAME_ACCESS;
#[derive(Clone, Debug)]
pub struct FdObject {
pub ty: host::__wasi_filetype_t,
pub raw_handle: RawHandle,
pub needs_close: bool,
// TODO: directories
}
#[derive(Clone, Debug)]
pub struct FdEntry {
pub fd_object: FdObject,
pub rights_base: host::__wasi_rights_t,
pub rights_inheriting: host::__wasi_rights_t,
pub preopen_path: Option<PathBuf>,
}
impl Drop for FdObject {
fn drop(&mut self) {
if self.needs_close {
unsafe {
if winapi::um::handleapi::CloseHandle(self.raw_handle) == 0 {
// TODO: use DWORD WINAPI GetLastError(void) to get error
eprintln!("FdObject::drop(): couldn't close raw Handle");
}
}
}
}
}
impl FdEntry {
pub fn from_file(file: File) -> Self {
unsafe { Self::from_raw_handle(file.into_raw_handle()) }
}
pub fn duplicate<F: AsRawHandle>(fd: &F) -> Self {
unsafe {
let source = fd.as_raw_handle();
let mut dest = 0 as RawHandle;
let cur_proc = GetCurrentProcess();
if DuplicateHandle(
cur_proc,
source,
cur_proc,
&mut dest,
0, // dwDesiredAccess; this flag is ignored if DUPLICATE_SAME_ACCESS is specified
FALSE,
DUPLICATE_SAME_ACCESS,
) == FALSE
{
panic!("Couldn't duplicate handle");
}
Self::from_raw_handle(dest)
}
}
}
impl FromRawHandle for FdEntry {
// TODO: implement
unsafe fn from_raw_handle(raw_handle: RawHandle) -> Self {
let (ty, rights_base, rights_inheriting) = (
host::__WASI_FILETYPE_REGULAR_FILE,
host::RIGHTS_REGULAR_FILE_BASE,
host::RIGHTS_REGULAR_FILE_INHERITING,
);
Self {
fd_object: FdObject {
ty,
raw_handle,
needs_close: true,
},
rights_base,
rights_inheriting,
preopen_path: None,
}
}
}

View File

@@ -0,0 +1,84 @@
//! WASI host types specific to Windows host.
#![allow(non_camel_case_types)]
#![allow(non_snake_case)]
#![allow(unused)]
use crate::host;
use std::marker::PhantomData;
use std::slice;
use winapi::shared::{ntdef, ws2def};
// these will be obsolete once https://github.com/rust-lang/rust/pull/60334
// lands in stable
pub struct IoVec<'a> {
vec: ws2def::WSABUF,
_p: PhantomData<&'a [u8]>,
}
pub struct IoVecMut<'a> {
vec: ws2def::WSABUF,
_p: PhantomData<&'a mut [u8]>,
}
impl<'a> IoVec<'a> {
#[inline]
pub fn new(buf: &'a [u8]) -> Self {
assert!(buf.len() <= ntdef::ULONG::max_value() as usize);
Self {
vec: ws2def::WSABUF {
len: buf.len() as ntdef::ULONG,
buf: buf.as_ptr() as *mut u8 as *mut ntdef::CHAR,
},
_p: PhantomData,
}
}
#[inline]
pub fn as_slice(&self) -> &[u8] {
unsafe { slice::from_raw_parts(self.vec.buf as *mut u8, self.vec.len as usize) }
}
}
impl<'a> IoVecMut<'a> {
#[inline]
pub fn new(buf: &'a mut [u8]) -> Self {
assert!(buf.len() <= ntdef::ULONG::max_value() as usize);
Self {
vec: ws2def::WSABUF {
len: buf.len() as ntdef::ULONG,
buf: buf.as_mut_ptr() as *mut u8 as *mut ntdef::CHAR,
},
_p: PhantomData,
}
}
#[inline]
pub fn as_slice(&self) -> &[u8] {
unsafe { slice::from_raw_parts(self.vec.buf as *mut u8, self.vec.len as usize) }
}
#[inline]
pub fn as_mut_slice(&mut self) -> &mut [u8] {
unsafe { slice::from_raw_parts_mut(self.vec.buf as *mut u8, self.vec.len as usize) }
}
}
pub unsafe fn ciovec_to_win<'a>(ciovec: &'a host::__wasi_ciovec_t) -> IoVec<'a> {
let slice = slice::from_raw_parts(ciovec.buf as *const u8, ciovec.buf_len);
IoVec::new(slice)
}
pub unsafe fn ciovec_to_win_mut<'a>(ciovec: &'a mut host::__wasi_ciovec_t) -> IoVecMut<'a> {
let slice = slice::from_raw_parts_mut(ciovec.buf as *mut u8, ciovec.buf_len);
IoVecMut::new(slice)
}
pub unsafe fn iovec_to_win<'a>(iovec: &'a host::__wasi_iovec_t) -> IoVec<'a> {
let slice = slice::from_raw_parts(iovec.buf as *const u8, iovec.buf_len);
IoVec::new(slice)
}
pub unsafe fn iovec_to_win_mut<'a>(iovec: &'a mut host::__wasi_iovec_t) -> IoVecMut<'a> {
let slice = slice::from_raw_parts_mut(iovec.buf as *mut u8, iovec.buf_len);
IoVecMut::new(slice)
}

View File

@@ -1,19 +1,25 @@
#![allow(non_camel_case_types)] #![allow(non_camel_case_types)]
#![allow(unused_unsafe)]
#![allow(unused)]
use super::host_impl;
use super::host_impl::IoVec;
use crate::ctx::WasiCtx; use crate::ctx::WasiCtx;
use crate::wasm32; use crate::memory::*;
use crate::{host, wasm32};
use crate::sys::hostcalls as hostcalls_impl;
use std::cmp;
use std::os::windows::prelude::OsStrExt;
use wasi_common_cbindgen::wasi_common_cbindgen; use wasi_common_cbindgen::wasi_common_cbindgen;
#[wasi_common_cbindgen] #[wasi_common_cbindgen]
pub fn fd_close(wasi_ctx: &mut WasiCtx, fd: wasm32::__wasi_fd_t) -> wasm32::__wasi_errno_t { pub fn fd_close(wasi_ctx: &mut WasiCtx, fd: wasm32::__wasi_fd_t) -> wasm32::__wasi_errno_t {
hostcalls_impl::fd_close(wasi_ctx, fd) unimplemented!("fd_close")
} }
#[wasi_common_cbindgen] #[wasi_common_cbindgen]
pub fn fd_datasync(wasi_ctx: &WasiCtx, fd: wasm32::__wasi_fd_t) -> wasm32::__wasi_errno_t { pub fn fd_datasync(wasi_ctx: &WasiCtx, fd: wasm32::__wasi_fd_t) -> wasm32::__wasi_errno_t {
hostcalls_impl::fd_datasync(wasi_ctx, fd) unimplemented!("fd_datasync")
} }
#[wasi_common_cbindgen] #[wasi_common_cbindgen]
@@ -26,7 +32,7 @@ pub fn fd_pread(
offset: wasm32::__wasi_filesize_t, offset: wasm32::__wasi_filesize_t,
nread: wasm32::uintptr_t, nread: wasm32::uintptr_t,
) -> wasm32::__wasi_errno_t { ) -> wasm32::__wasi_errno_t {
hostcalls_impl::fd_pread(wasi_ctx, memory, fd, iovs_ptr, iovs_len, offset, nread) unimplemented!("fd_pread")
} }
#[wasi_common_cbindgen] #[wasi_common_cbindgen]
@@ -39,7 +45,7 @@ pub fn fd_pwrite(
offset: wasm32::__wasi_filesize_t, offset: wasm32::__wasi_filesize_t,
nwritten: wasm32::uintptr_t, nwritten: wasm32::uintptr_t,
) -> wasm32::__wasi_errno_t { ) -> wasm32::__wasi_errno_t {
hostcalls_impl::fd_pwrite(wasi_ctx, memory, fd, iovs_ptr, iovs_len, offset, nwritten) unimplemented!("fd_pwrite")
} }
#[wasi_common_cbindgen] #[wasi_common_cbindgen]
@@ -51,7 +57,7 @@ pub fn fd_read(
iovs_len: wasm32::size_t, iovs_len: wasm32::size_t,
nread: wasm32::uintptr_t, nread: wasm32::uintptr_t,
) -> wasm32::__wasi_errno_t { ) -> wasm32::__wasi_errno_t {
hostcalls_impl::fd_read(wasi_ctx, memory, fd, iovs_ptr, iovs_len, nread) unimplemented!("fd_read")
} }
#[wasi_common_cbindgen] #[wasi_common_cbindgen]
@@ -60,7 +66,7 @@ pub fn fd_renumber(
from: wasm32::__wasi_fd_t, from: wasm32::__wasi_fd_t,
to: wasm32::__wasi_fd_t, to: wasm32::__wasi_fd_t,
) -> wasm32::__wasi_errno_t { ) -> wasm32::__wasi_errno_t {
hostcalls_impl::fd_renumber(wasi_ctx, from, to) unimplemented!("fd_renumber")
} }
#[wasi_common_cbindgen] #[wasi_common_cbindgen]
@@ -72,7 +78,7 @@ pub fn fd_seek(
whence: wasm32::__wasi_whence_t, whence: wasm32::__wasi_whence_t,
newoffset: wasm32::uintptr_t, newoffset: wasm32::uintptr_t,
) -> wasm32::__wasi_errno_t { ) -> wasm32::__wasi_errno_t {
hostcalls_impl::fd_seek(wasi_ctx, memory, fd, offset, whence, newoffset) unimplemented!("fd_seek")
} }
#[wasi_common_cbindgen] #[wasi_common_cbindgen]
@@ -82,7 +88,7 @@ pub fn fd_tell(
fd: wasm32::__wasi_fd_t, fd: wasm32::__wasi_fd_t,
newoffset: wasm32::uintptr_t, newoffset: wasm32::uintptr_t,
) -> wasm32::__wasi_errno_t { ) -> wasm32::__wasi_errno_t {
hostcalls_impl::fd_tell(wasi_ctx, memory, fd, newoffset) unimplemented!("fd_tell")
} }
#[wasi_common_cbindgen] #[wasi_common_cbindgen]
@@ -90,9 +96,9 @@ pub fn fd_fdstat_get(
wasi_ctx: &WasiCtx, wasi_ctx: &WasiCtx,
memory: &mut [u8], memory: &mut [u8],
fd: wasm32::__wasi_fd_t, fd: wasm32::__wasi_fd_t,
fdstat_ptr: wasm32::uintptr_t, fdstat_ptr: wasm32::uintptr_t, // *mut wasm32::__wasi_fdstat_t
) -> wasm32::__wasi_errno_t { ) -> wasm32::__wasi_errno_t {
hostcalls_impl::fd_fdstat_get(wasi_ctx, memory, fd, fdstat_ptr) unimplemented!("fd_fdstat_get")
} }
#[wasi_common_cbindgen] #[wasi_common_cbindgen]
@@ -101,7 +107,7 @@ pub fn fd_fdstat_set_flags(
fd: wasm32::__wasi_fd_t, fd: wasm32::__wasi_fd_t,
fdflags: wasm32::__wasi_fdflags_t, fdflags: wasm32::__wasi_fdflags_t,
) -> wasm32::__wasi_errno_t { ) -> wasm32::__wasi_errno_t {
hostcalls_impl::fd_fdstat_set_flags(wasi_ctx, fd, fdflags) unimplemented!("fd_fdstat_set_flags")
} }
#[wasi_common_cbindgen] #[wasi_common_cbindgen]
@@ -111,12 +117,12 @@ pub fn fd_fdstat_set_rights(
fs_rights_base: wasm32::__wasi_rights_t, fs_rights_base: wasm32::__wasi_rights_t,
fs_rights_inheriting: wasm32::__wasi_rights_t, fs_rights_inheriting: wasm32::__wasi_rights_t,
) -> wasm32::__wasi_errno_t { ) -> wasm32::__wasi_errno_t {
hostcalls_impl::fd_fdstat_set_rights(wasi_ctx, fd, fs_rights_base, fs_rights_inheriting) unimplemented!("fd_fdstat_set_rights")
} }
#[wasi_common_cbindgen] #[wasi_common_cbindgen]
pub fn fd_sync(wasi_ctx: &WasiCtx, fd: wasm32::__wasi_fd_t) -> wasm32::__wasi_errno_t { pub fn fd_sync(wasi_ctx: &WasiCtx, fd: wasm32::__wasi_fd_t) -> wasm32::__wasi_errno_t {
hostcalls_impl::fd_sync(wasi_ctx, fd) unimplemented!("fd_sync")
} }
#[wasi_common_cbindgen] #[wasi_common_cbindgen]
@@ -128,7 +134,46 @@ pub fn fd_write(
iovs_len: wasm32::size_t, iovs_len: wasm32::size_t,
nwritten: wasm32::uintptr_t, nwritten: wasm32::uintptr_t,
) -> wasm32::__wasi_errno_t { ) -> wasm32::__wasi_errno_t {
hostcalls_impl::fd_write(wasi_ctx, memory, fd, iovs_ptr, iovs_len, nwritten) use winapi::shared::minwindef::{DWORD, LPVOID};
use winapi::shared::ws2def::WSABUF;
use winapi::um::fileapi::WriteFile;
let fd = dec_fd(fd);
let mut iovs = match dec_iovec_slice(memory, iovs_ptr, iovs_len) {
Ok(iovs) => iovs,
Err(e) => return enc_errno(e),
};
let fe = match wasi_ctx.get_fd_entry(fd, host::__WASI_RIGHT_FD_WRITE.into(), 0) {
Ok(fe) => fe,
Err(e) => return enc_errno(e),
};
let iovs: Vec<IoVec> = iovs
.iter()
.map(|iov| unsafe { host_impl::iovec_to_win(iov) })
.collect();
let buf = iovs
.iter()
.find(|b| !b.as_slice().is_empty())
.map_or(&[][..], |b| b.as_slice());
let mut host_nwritten = 0;
let len = cmp::min(buf.len(), <DWORD>::max_value() as usize) as DWORD;
unsafe {
WriteFile(
fe.fd_object.raw_handle,
buf.as_ptr() as LPVOID,
len,
&mut host_nwritten,
std::ptr::null_mut(),
)
};
enc_usize_byref(memory, nwritten, host_nwritten as usize)
.map(|_| wasm32::__WASI_ESUCCESS)
.unwrap_or_else(|e| e)
} }
#[wasi_common_cbindgen] #[wasi_common_cbindgen]
@@ -139,7 +184,7 @@ pub fn fd_advise(
len: wasm32::__wasi_filesize_t, len: wasm32::__wasi_filesize_t,
advice: wasm32::__wasi_advice_t, advice: wasm32::__wasi_advice_t,
) -> wasm32::__wasi_errno_t { ) -> wasm32::__wasi_errno_t {
hostcalls_impl::fd_advise(wasi_ctx, fd, offset, len, advice) unimplemented!("fd_advise")
} }
#[wasi_common_cbindgen] #[wasi_common_cbindgen]
@@ -149,7 +194,7 @@ pub fn fd_allocate(
offset: wasm32::__wasi_filesize_t, offset: wasm32::__wasi_filesize_t,
len: wasm32::__wasi_filesize_t, len: wasm32::__wasi_filesize_t,
) -> wasm32::__wasi_errno_t { ) -> wasm32::__wasi_errno_t {
hostcalls_impl::fd_allocate(wasi_ctx, fd, offset, len) unimplemented!("fd_allocate")
} }
#[wasi_common_cbindgen] #[wasi_common_cbindgen]
@@ -160,7 +205,7 @@ pub fn path_create_directory(
path_ptr: wasm32::uintptr_t, path_ptr: wasm32::uintptr_t,
path_len: wasm32::size_t, path_len: wasm32::size_t,
) -> wasm32::__wasi_errno_t { ) -> wasm32::__wasi_errno_t {
hostcalls_impl::path_create_directory(wasi_ctx, memory, dirfd, path_ptr, path_len) unimplemented!("path_create_directory")
} }
#[wasi_common_cbindgen] #[wasi_common_cbindgen]
@@ -168,24 +213,14 @@ pub fn path_link(
wasi_ctx: &WasiCtx, wasi_ctx: &WasiCtx,
memory: &mut [u8], memory: &mut [u8],
old_dirfd: wasm32::__wasi_fd_t, old_dirfd: wasm32::__wasi_fd_t,
old_flags: wasm32::__wasi_lookupflags_t, _old_flags: wasm32::__wasi_lookupflags_t,
old_path_ptr: wasm32::uintptr_t, old_path_ptr: wasm32::uintptr_t,
old_path_len: wasm32::size_t, old_path_len: wasm32::size_t,
new_dirfd: wasm32::__wasi_fd_t, new_dirfd: wasm32::__wasi_fd_t,
new_path_ptr: wasm32::uintptr_t, new_path_ptr: wasm32::uintptr_t,
new_path_len: wasm32::size_t, new_path_len: wasm32::size_t,
) -> wasm32::__wasi_errno_t { ) -> wasm32::__wasi_errno_t {
hostcalls_impl::path_link( unimplemented!("path_link")
wasi_ctx,
memory,
old_dirfd,
old_flags,
old_path_ptr,
old_path_len,
new_dirfd,
new_path_ptr,
new_path_len,
)
} }
#[wasi_common_cbindgen] #[wasi_common_cbindgen]
@@ -202,19 +237,7 @@ pub fn path_open(
fs_flags: wasm32::__wasi_fdflags_t, fs_flags: wasm32::__wasi_fdflags_t,
fd_out_ptr: wasm32::uintptr_t, fd_out_ptr: wasm32::uintptr_t,
) -> wasm32::__wasi_errno_t { ) -> wasm32::__wasi_errno_t {
hostcalls_impl::path_open( unimplemented!("path_open")
wasi_ctx,
memory,
dirfd,
dirflags,
path_ptr,
path_len,
oflags,
fs_rights_base,
fs_rights_inheriting,
fs_flags,
fd_out_ptr,
)
} }
#[wasi_common_cbindgen] #[wasi_common_cbindgen]
@@ -227,7 +250,7 @@ pub fn fd_readdir(
cookie: wasm32::__wasi_dircookie_t, cookie: wasm32::__wasi_dircookie_t,
buf_used: wasm32::uintptr_t, buf_used: wasm32::uintptr_t,
) -> wasm32::__wasi_errno_t { ) -> wasm32::__wasi_errno_t {
hostcalls_impl::fd_readdir(wasi_ctx, memory, fd, buf, buf_len, cookie, buf_used) unimplemented!("fd_readdir")
} }
#[wasi_common_cbindgen] #[wasi_common_cbindgen]
@@ -241,9 +264,7 @@ pub fn path_readlink(
buf_len: wasm32::size_t, buf_len: wasm32::size_t,
buf_used: wasm32::uintptr_t, buf_used: wasm32::uintptr_t,
) -> wasm32::__wasi_errno_t { ) -> wasm32::__wasi_errno_t {
hostcalls_impl::path_readlink( unimplemented!("path_readlink")
wasi_ctx, memory, dirfd, path_ptr, path_len, buf_ptr, buf_len, buf_used,
)
} }
#[wasi_common_cbindgen] #[wasi_common_cbindgen]
@@ -257,16 +278,7 @@ pub fn path_rename(
new_path_ptr: wasm32::uintptr_t, new_path_ptr: wasm32::uintptr_t,
new_path_len: wasm32::size_t, new_path_len: wasm32::size_t,
) -> wasm32::__wasi_errno_t { ) -> wasm32::__wasi_errno_t {
hostcalls_impl::path_rename( unimplemented!("path_rename")
wasi_ctx,
memory,
old_dirfd,
old_path_ptr,
old_path_len,
new_dirfd,
new_path_ptr,
new_path_len,
)
} }
#[wasi_common_cbindgen] #[wasi_common_cbindgen]
@@ -276,7 +288,7 @@ pub fn fd_filestat_get(
fd: wasm32::__wasi_fd_t, fd: wasm32::__wasi_fd_t,
filestat_ptr: wasm32::uintptr_t, filestat_ptr: wasm32::uintptr_t,
) -> wasm32::__wasi_errno_t { ) -> wasm32::__wasi_errno_t {
hostcalls_impl::fd_filestat_get(wasi_ctx, memory, fd, filestat_ptr) unimplemented!("fd_filestat_get")
} }
#[wasi_common_cbindgen] #[wasi_common_cbindgen]
@@ -287,7 +299,7 @@ pub fn fd_filestat_set_times(
st_mtim: wasm32::__wasi_timestamp_t, st_mtim: wasm32::__wasi_timestamp_t,
fst_flags: wasm32::__wasi_fstflags_t, fst_flags: wasm32::__wasi_fstflags_t,
) -> wasm32::__wasi_errno_t { ) -> wasm32::__wasi_errno_t {
hostcalls_impl::fd_filestat_set_times(wasi_ctx, fd, st_atim, st_mtim, fst_flags) unimplemented!("fd_filestat_set_times")
} }
#[wasi_common_cbindgen] #[wasi_common_cbindgen]
@@ -296,7 +308,7 @@ pub fn fd_filestat_set_size(
fd: wasm32::__wasi_fd_t, fd: wasm32::__wasi_fd_t,
st_size: wasm32::__wasi_filesize_t, st_size: wasm32::__wasi_filesize_t,
) -> wasm32::__wasi_errno_t { ) -> wasm32::__wasi_errno_t {
hostcalls_impl::fd_filestat_set_size(wasi_ctx, fd, st_size) unimplemented!("fd_filestat_set_size")
} }
#[wasi_common_cbindgen] #[wasi_common_cbindgen]
@@ -309,15 +321,7 @@ pub fn path_filestat_get(
path_len: wasm32::size_t, path_len: wasm32::size_t,
filestat_ptr: wasm32::uintptr_t, filestat_ptr: wasm32::uintptr_t,
) -> wasm32::__wasi_errno_t { ) -> wasm32::__wasi_errno_t {
hostcalls_impl::path_filestat_get( unimplemented!("path_filestat_get")
wasi_ctx,
memory,
dirfd,
dirflags,
path_ptr,
path_len,
filestat_ptr,
)
} }
#[wasi_common_cbindgen] #[wasi_common_cbindgen]
@@ -332,9 +336,7 @@ pub fn path_filestat_set_times(
st_mtim: wasm32::__wasi_timestamp_t, st_mtim: wasm32::__wasi_timestamp_t,
fst_flags: wasm32::__wasi_fstflags_t, fst_flags: wasm32::__wasi_fstflags_t,
) -> wasm32::__wasi_errno_t { ) -> wasm32::__wasi_errno_t {
hostcalls_impl::path_filestat_set_times( unimplemented!("path_filestat_set_times")
wasi_ctx, memory, dirfd, dirflags, path_ptr, path_len, st_atim, st_mtim, fst_flags,
)
} }
#[wasi_common_cbindgen] #[wasi_common_cbindgen]
@@ -347,15 +349,7 @@ pub fn path_symlink(
new_path_ptr: wasm32::uintptr_t, new_path_ptr: wasm32::uintptr_t,
new_path_len: wasm32::size_t, new_path_len: wasm32::size_t,
) -> wasm32::__wasi_errno_t { ) -> wasm32::__wasi_errno_t {
hostcalls_impl::path_symlink( unimplemented!("path_symlink")
wasi_ctx,
memory,
old_path_ptr,
old_path_len,
dirfd,
new_path_ptr,
new_path_len,
)
} }
#[wasi_common_cbindgen] #[wasi_common_cbindgen]
@@ -366,7 +360,7 @@ pub fn path_unlink_file(
path_ptr: wasm32::uintptr_t, path_ptr: wasm32::uintptr_t,
path_len: wasm32::size_t, path_len: wasm32::size_t,
) -> wasm32::__wasi_errno_t { ) -> wasm32::__wasi_errno_t {
hostcalls_impl::path_unlink_file(wasi_ctx, memory, dirfd, path_ptr, path_len) unimplemented!("path_unlink_file")
} }
#[wasi_common_cbindgen] #[wasi_common_cbindgen]
@@ -377,7 +371,7 @@ pub fn path_remove_directory(
path_ptr: wasm32::uintptr_t, path_ptr: wasm32::uintptr_t,
path_len: wasm32::size_t, path_len: wasm32::size_t,
) -> wasm32::__wasi_errno_t { ) -> wasm32::__wasi_errno_t {
hostcalls_impl::path_remove_directory(wasi_ctx, memory, dirfd, path_ptr, path_len) unimplemented!("path_remove_directory")
} }
#[wasi_common_cbindgen] #[wasi_common_cbindgen]
@@ -387,7 +381,35 @@ pub fn fd_prestat_get(
fd: wasm32::__wasi_fd_t, fd: wasm32::__wasi_fd_t,
prestat_ptr: wasm32::uintptr_t, prestat_ptr: wasm32::uintptr_t,
) -> wasm32::__wasi_errno_t { ) -> wasm32::__wasi_errno_t {
hostcalls_impl::fd_prestat_get(wasi_ctx, memory, fd, prestat_ptr) let fd = dec_fd(fd);
// TODO: is this the correct right for this?
match wasi_ctx.get_fd_entry(fd, host::__WASI_RIGHT_PATH_OPEN.into(), 0) {
Ok(fe) => {
if let Some(po_path) = &fe.preopen_path {
if fe.fd_object.ty != host::__WASI_FILETYPE_DIRECTORY {
return wasm32::__WASI_ENOTDIR;
}
enc_prestat_byref(
memory,
prestat_ptr,
host::__wasi_prestat_t {
pr_type: host::__WASI_PREOPENTYPE_DIR,
u: host::__wasi_prestat_t___wasi_prestat_u {
dir: host::__wasi_prestat_t___wasi_prestat_u___wasi_prestat_u_dir_t {
// TODO: clean up
pr_name_len: po_path.as_os_str().encode_wide().count() * 2,
},
},
},
)
.map(|_| wasm32::__WASI_ESUCCESS)
.unwrap_or_else(|e| e)
} else {
wasm32::__WASI_ENOTSUP
}
}
Err(e) => enc_errno(e),
}
} }
#[wasi_common_cbindgen] #[wasi_common_cbindgen]
@@ -398,5 +420,33 @@ pub fn fd_prestat_dir_name(
path_ptr: wasm32::uintptr_t, path_ptr: wasm32::uintptr_t,
path_len: wasm32::size_t, path_len: wasm32::size_t,
) -> wasm32::__wasi_errno_t { ) -> wasm32::__wasi_errno_t {
hostcalls_impl::fd_prestat_dir_name(wasi_ctx, memory, fd, path_ptr, path_len) let fd = dec_fd(fd);
match wasi_ctx.get_fd_entry(fd, host::__WASI_RIGHT_PATH_OPEN.into(), 0) {
Ok(fe) => {
if let Some(po_path) = &fe.preopen_path {
if fe.fd_object.ty != host::__WASI_FILETYPE_DIRECTORY {
return wasm32::__WASI_ENOTDIR;
}
// TODO: clean up
let path_bytes = &po_path
.as_os_str()
.encode_wide()
.map(u16::to_le_bytes)
.fold(Vec::new(), |mut acc, bytes| {
acc.extend_from_slice(&bytes);
acc
});
if path_bytes.len() > dec_usize(path_len) {
return wasm32::__WASI_ENAMETOOLONG;
}
enc_slice_of(memory, path_bytes, path_ptr)
.map(|_| wasm32::__WASI_ESUCCESS)
.unwrap_or_else(|e| e)
} else {
wasm32::__WASI_ENOTSUP
}
}
Err(e) => enc_errno(e),
}
} }

View File

@@ -0,0 +1,46 @@
#![allow(non_camel_case_types)]
#![allow(unused_unsafe)]
#![allow(unused)]
use super::host_impl;
use crate::memory::*;
use crate::{host, wasm32};
use std::cmp;
use std::time::SystemTime;
use wasi_common_cbindgen::wasi_common_cbindgen;
#[wasi_common_cbindgen]
pub fn clock_res_get(
memory: &mut [u8],
clock_id: wasm32::__wasi_clockid_t,
resolution_ptr: wasm32::uintptr_t,
) -> wasm32::__wasi_errno_t {
unimplemented!("clock_res_get")
}
#[wasi_common_cbindgen]
pub fn clock_time_get(
memory: &mut [u8],
clock_id: wasm32::__wasi_clockid_t,
precision: wasm32::__wasi_timestamp_t,
time_ptr: wasm32::uintptr_t,
) -> wasm32::__wasi_errno_t {
unimplemented!("clock_time_get")
}
#[wasi_common_cbindgen]
pub fn poll_oneoff(
memory: &mut [u8],
input: wasm32::uintptr_t,
output: wasm32::uintptr_t,
nsubscriptions: wasm32::size_t,
nevents: wasm32::uintptr_t,
) -> wasm32::__wasi_errno_t {
unimplemented!("poll_oneoff")
}
#[wasi_common_cbindgen]
pub fn sched_yield() -> wasm32::__wasi_errno_t {
unimplemented!("sched_yield")
}

View File

@@ -0,0 +1,11 @@
//! Windows-specific hostcalls that implement
//! [WASI](https://github.com/CraneStation/wasmtime-wasi/blob/wasi/docs/WASI-overview.md).
mod fs;
mod misc;
mod sock;
use super::host_impl;
pub use self::fs::*;
pub use self::misc::*;
pub use self::sock::*;

View File

@@ -1,9 +1,9 @@
#![allow(non_camel_case_types)] #![allow(non_camel_case_types)]
#![allow(unused_unsafe)]
#![allow(unused)]
use crate::ctx::WasiCtx; use crate::ctx::WasiCtx;
use crate::wasm32; use crate::wasm32;
use crate::sys::hostcalls as hostcalls_impl;
use wasi_common_cbindgen::wasi_common_cbindgen; use wasi_common_cbindgen::wasi_common_cbindgen;
#[wasi_common_cbindgen] #[wasi_common_cbindgen]
@@ -17,16 +17,7 @@ pub fn sock_recv(
ro_datalen: wasm32::uintptr_t, ro_datalen: wasm32::uintptr_t,
ro_flags: wasm32::uintptr_t, ro_flags: wasm32::uintptr_t,
) -> wasm32::__wasi_errno_t { ) -> wasm32::__wasi_errno_t {
hostcalls_impl::sock_recv( unimplemented!("sock_recv")
wasi_ctx,
memory,
sock,
ri_data,
ri_data_len,
ri_flags,
ro_datalen,
ro_flags,
)
} }
#[wasi_common_cbindgen] #[wasi_common_cbindgen]
@@ -39,15 +30,7 @@ pub fn sock_send(
si_flags: wasm32::__wasi_siflags_t, si_flags: wasm32::__wasi_siflags_t,
so_datalen: wasm32::uintptr_t, so_datalen: wasm32::uintptr_t,
) -> wasm32::__wasi_errno_t { ) -> wasm32::__wasi_errno_t {
hostcalls_impl::sock_send( unimplemented!("sock_send")
wasi_ctx,
memory,
sock,
si_data,
si_data_len,
si_flags,
so_datalen,
)
} }
#[wasi_common_cbindgen] #[wasi_common_cbindgen]
@@ -57,5 +40,5 @@ pub fn sock_shutdown(
sock: wasm32::__wasi_fd_t, sock: wasm32::__wasi_fd_t,
how: wasm32::__wasi_sdflags_t, how: wasm32::__wasi_sdflags_t,
) -> wasm32::__wasi_errno_t { ) -> wasm32::__wasi_errno_t {
hostcalls_impl::sock_shutdown(wasi_ctx, memory, sock, how) unimplemented!("sock_shutdown")
} }

View File

@@ -0,0 +1,9 @@
pub mod fdentry;
mod host_impl;
pub mod hostcalls;
use std::fs::File;
pub fn dev_null() -> File {
File::open("NUL").expect("failed to open NUL")
}