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::sys::dev_null;
use crate::sys::fdmap::{FdEntry, FdMap};
use crate::sys::fdentry::FdEntry;
use failure::{bail, format_err, Error};
use std::collections::HashMap;
@@ -11,7 +11,7 @@ use std::io::{stderr, stdin, stdout};
use std::path::{Path, PathBuf};
pub struct WasiCtxBuilder {
fds: FdMap,
fds: HashMap<host::__wasi_fd_t, FdEntry>,
preopens: HashMap<PathBuf, File>,
args: Vec<CString>,
env: HashMap<CString, CString>,
@@ -21,15 +21,15 @@ impl WasiCtxBuilder {
/// Builder for a new `WasiCtx`.
pub fn new() -> Self {
let mut builder = Self {
fds: FdMap::new(),
fds: HashMap::new(),
preopens: HashMap::new(),
args: vec![],
env: HashMap::new(),
};
builder.fds.insert_fd_entry_at(0, FdEntry::from_file(dev_null()));
builder.fds.insert_fd_entry_at(1, FdEntry::from_file(dev_null()));
builder.fds.insert_fd_entry_at(2, FdEntry::from_file(dev_null()));
builder.fds.insert(0, FdEntry::from_file(dev_null()));
builder.fds.insert(1, FdEntry::from_file(dev_null()));
builder.fds.insert(2, FdEntry::from_file(dev_null()));
builder
}
@@ -62,9 +62,9 @@ impl WasiCtxBuilder {
}
pub fn inherit_stdio(mut self) -> Self {
self.fds.insert_fd_entry_at(0, FdEntry::duplicate(&stdin()));
self.fds.insert_fd_entry_at(1, FdEntry::duplicate(&stdout()));
self.fds.insert_fd_entry_at(2, FdEntry::duplicate(&stderr()));
self.fds.insert(0, FdEntry::duplicate(&stdin()));
self.fds.insert(1, FdEntry::duplicate(&stdout()));
self.fds.insert(2, FdEntry::duplicate(&stderr()));
self
}
@@ -106,15 +106,22 @@ impl WasiCtxBuilder {
}
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 {
if !dir.metadata()?.is_dir() {
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);
fe.preopen_path = Some(guest_path);
self.fds
.insert_fd_entry(fe)
.map_err(|_| format_err!("not enough file handles"))?;
self.fds.insert(preopen_fd, fe);
preopen_fd += 1;
}
let env = self
@@ -139,7 +146,7 @@ impl WasiCtxBuilder {
#[derive(Debug)]
pub struct WasiCtx {
pub fds: FdMap,
pub fds: HashMap<host::__wasi_fd_t, FdEntry>,
pub args: Vec<CString>,
pub env: Vec<CString>,
}
@@ -167,13 +174,33 @@ impl WasiCtx {
rights_base: host::__wasi_rights_t,
rights_inheriting: host::__wasi_rights_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(
&mut self,
fe: FdEntry,
) -> 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::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 wasi_common_cbindgen::wasi_common_cbindgen;
pub use crate::sys::hostcalls::*;
#[wasi_common_cbindgen]
pub fn args_get(
wasi_ctx: &WasiCtx,
@@ -67,25 +68,6 @@ pub fn args_sizes_get(
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]
pub fn environ_get(
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]
pub fn proc_exit(rval: wasm32::__wasi_exitcode_t) -> () {
// TODO: Rather than call std::process::exit here, we should trigger a
@@ -171,11 +142,6 @@ pub fn proc_raise(
unimplemented!("proc_raise")
}
#[wasi_common_cbindgen]
pub fn sched_yield() -> wasm32::__wasi_errno_t {
hostcalls_impl::sched_yield()
}
#[wasi_common_cbindgen]
pub fn random_get(
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 sys;
pub mod memory;
pub mod host;
pub mod hostcalls;
pub mod memory;
pub mod wasm32;
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.
#![allow(unused)]
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::From as _0;
use std::mem::{align_of, size_of};
use std::ptr;
use std::slice;

View File

@@ -1,9 +1,8 @@
use crate::host;
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::collections::HashMap;
#[derive(Clone, Debug)]
pub struct FdObject {
@@ -21,11 +20,6 @@ pub struct FdEntry {
pub preopen_path: Option<PathBuf>,
}
#[derive(Debug)]
pub struct FdMap {
entries: HashMap<host::__wasi_fd_t, FdEntry>,
}
impl Drop for FdObject {
fn drop(&mut self) {
if self.needs_close {
@@ -148,63 +142,3 @@ pub unsafe fn determine_type_rights(
};
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(dead_code)]
use crate::host;
use crate::memory;
use crate::wasm32;
pub fn errno_from_nix(errno: nix::errno::Errno) -> host::__wasi_errno_t {
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::ESRCH => host::__WASI_ESRCH,
nix::errno::Errno::EINTR => host::__WASI_EINTR,
nix::errno::Errno::EIO => host::__WASI_EIO,
nix::errno::Errno::ENXIO => host::__WASI_ENXIO,
nix::errno::Errno::E2BIG => host::__WASI_E2BIG,
nix::errno::Errno::ESRCH => host::__WASI_ESRCH,
nix::errno::Errno::EINTR => host::__WASI_EINTR,
nix::errno::Errno::EIO => host::__WASI_EIO,
nix::errno::Errno::ENXIO => host::__WASI_ENXIO,
nix::errno::Errno::E2BIG => host::__WASI_E2BIG,
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::EAGAIN => host::__WASI_EAGAIN,
nix::errno::Errno::ENOMEM => host::__WASI_ENOMEM,
nix::errno::Errno::EACCES => host::__WASI_EACCES,
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::EXDEV => host::__WASI_EXDEV,
nix::errno::Errno::EXDEV => host::__WASI_EXDEV,
nix::errno::Errno::ENODEV => host::__WASI_ENODEV,
nix::errno::Errno::ENOTDIR => host::__WASI_ENOTDIR,
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::ENOTTY => host::__WASI_ENOTTY,
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::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::EPIPE => host::__WASI_EPIPE,
nix::errno::Errno::EDOM => host::__WASI_EDOM,
nix::errno::Errno::EPIPE => host::__WASI_EPIPE,
nix::errno::Errno::EDOM => host::__WASI_EDOM,
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::ENOLCK => host::__WASI_ENOLCK,
nix::errno::Errno::ENOSYS => host::__WASI_ENOSYS,
nix::errno::Errno::ENOTEMPTY => host::__WASI_ENOTEMPTY,
nix::errno::Errno::ELOOP => host::__WASI_ELOOP,
nix::errno::Errno::ENOMSG => host::__WASI_ENOMSG,
nix::errno::Errno::EIDRM => host::__WASI_EIDRM,
nix::errno::Errno::ENOLINK => host::__WASI_ENOLINK,
nix::errno::Errno::EPROTO => host::__WASI_EPROTO,
nix::errno::Errno::EMULTIHOP => host::__WASI_EMULTIHOP,
nix::errno::Errno::EBADMSG => host::__WASI_EBADMSG,
nix::errno::Errno::EOVERFLOW => host::__WASI_EOVERFLOW,
nix::errno::Errno::EILSEQ => host::__WASI_EILSEQ,
nix::errno::Errno::ENOTSOCK => host::__WASI_ENOTSOCK,
nix::errno::Errno::ENOLCK => host::__WASI_ENOLCK,
nix::errno::Errno::ENOSYS => host::__WASI_ENOSYS,
nix::errno::Errno::ENOTEMPTY => host::__WASI_ENOTEMPTY,
nix::errno::Errno::ELOOP => host::__WASI_ELOOP,
nix::errno::Errno::ENOMSG => host::__WASI_ENOMSG,
nix::errno::Errno::EIDRM => host::__WASI_EIDRM,
nix::errno::Errno::ENOLINK => host::__WASI_ENOLINK,
nix::errno::Errno::EPROTO => host::__WASI_EPROTO,
nix::errno::Errno::EMULTIHOP => host::__WASI_EMULTIHOP,
nix::errno::Errno::EBADMSG => host::__WASI_EBADMSG,
nix::errno::Errno::EOVERFLOW => host::__WASI_EOVERFLOW,
nix::errno::Errno::EILSEQ => host::__WASI_EILSEQ,
nix::errno::Errno::ENOTSOCK => host::__WASI_ENOTSOCK,
nix::errno::Errno::EDESTADDRREQ => host::__WASI_EDESTADDRREQ,
nix::errno::Errno::EMSGSIZE => host::__WASI_EMSGSIZE,
nix::errno::Errno::EPROTOTYPE => host::__WASI_EPROTOTYPE,
nix::errno::Errno::ENOPROTOOPT => host::__WASI_ENOPROTOOPT,
nix::errno::Errno::EMSGSIZE => host::__WASI_EMSGSIZE,
nix::errno::Errno::EPROTOTYPE => host::__WASI_EPROTOTYPE,
nix::errno::Errno::ENOPROTOOPT => host::__WASI_ENOPROTOOPT,
nix::errno::Errno::EPROTONOSUPPORT => host::__WASI_EPROTONOSUPPORT,
nix::errno::Errno::EAFNOSUPPORT => host::__WASI_EAFNOSUPPORT,
nix::errno::Errno::EADDRINUSE => host::__WASI_EADDRINUSE,
nix::errno::Errno::EAFNOSUPPORT => host::__WASI_EAFNOSUPPORT,
nix::errno::Errno::EADDRINUSE => host::__WASI_EADDRINUSE,
nix::errno::Errno::EADDRNOTAVAIL => host::__WASI_EADDRNOTAVAIL,
nix::errno::Errno::ENETDOWN => host::__WASI_ENETDOWN,
nix::errno::Errno::ENETUNREACH => host::__WASI_ENETUNREACH,
nix::errno::Errno::ENETRESET => host::__WASI_ENETRESET,
nix::errno::Errno::ECONNABORTED => host::__WASI_ECONNABORTED,
nix::errno::Errno::ECONNRESET => host::__WASI_ECONNRESET,
nix::errno::Errno::ENOBUFS => host::__WASI_ENOBUFS,
nix::errno::Errno::EISCONN => host::__WASI_EISCONN,
nix::errno::Errno::ENOTCONN => host::__WASI_ENOTCONN,
nix::errno::Errno::ETIMEDOUT => host::__WASI_ETIMEDOUT,
nix::errno::Errno::ECONNREFUSED => host::__WASI_ECONNREFUSED,
nix::errno::Errno::EHOSTUNREACH => host::__WASI_EHOSTUNREACH,
nix::errno::Errno::EALREADY => host::__WASI_EALREADY,
nix::errno::Errno::EINPROGRESS => host::__WASI_EINPROGRESS,
nix::errno::Errno::ESTALE => host::__WASI_ESTALE,
nix::errno::Errno::EDQUOT => host::__WASI_EDQUOT,
nix::errno::Errno::ECANCELED => host::__WASI_ECANCELED,
nix::errno::Errno::EOWNERDEAD => host::__WASI_EOWNERDEAD,
nix::errno::Errno::ENETDOWN => host::__WASI_ENETDOWN,
nix::errno::Errno::ENETUNREACH => host::__WASI_ENETUNREACH,
nix::errno::Errno::ENETRESET => host::__WASI_ENETRESET,
nix::errno::Errno::ECONNABORTED => host::__WASI_ECONNABORTED,
nix::errno::Errno::ECONNRESET => host::__WASI_ECONNRESET,
nix::errno::Errno::ENOBUFS => host::__WASI_ENOBUFS,
nix::errno::Errno::EISCONN => host::__WASI_EISCONN,
nix::errno::Errno::ENOTCONN => host::__WASI_ENOTCONN,
nix::errno::Errno::ETIMEDOUT => host::__WASI_ETIMEDOUT,
nix::errno::Errno::ECONNREFUSED => host::__WASI_ECONNREFUSED,
nix::errno::Errno::EHOSTUNREACH => host::__WASI_EHOSTUNREACH,
nix::errno::Errno::EALREADY => host::__WASI_EALREADY,
nix::errno::Errno::EINPROGRESS => host::__WASI_EINPROGRESS,
nix::errno::Errno::ESTALE => host::__WASI_ESTALE,
nix::errno::Errno::EDQUOT => host::__WASI_EDQUOT,
nix::errno::Errno::ECANCELED => host::__WASI_ECANCELED,
nix::errno::Errno::EOWNERDEAD => host::__WASI_EOWNERDEAD,
nix::errno::Errno::ENOTRECOVERABLE => host::__WASI_ENOTRECOVERABLE,
_ => 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);
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_ino: ino,
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_ctim: filestat.st_ctime as host::__wasi_timestamp_t,
st_mtim: filestat.st_mtime as host::__wasi_timestamp_t,
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(unused_unsafe)]
use crate::sys::fdmap::{determine_type_rights, FdEntry};
use crate::sys::host as host_impl;
use super::fdentry::{determine_type_rights, FdEntry};
use super::fs_helpers::*;
use super::host_impl;
use crate::ctx::WasiCtx;
use crate::memory::*;
use crate::{host, wasm32};
use super::fs_helpers::*;
use nix::libc::{self, c_long, c_void, off_t};
use std::ffi::OsStr;
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 {
let fd = dec_fd(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 {
let host_fd = dec_fd(fd);
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
}
#[wasi_common_cbindgen]
pub fn fd_pread(
wasi_ctx: &WasiCtx,
memory: &mut [u8],
@@ -106,6 +109,7 @@ pub fn fd_pread(
.unwrap_or_else(|e| e)
}
#[wasi_common_cbindgen]
pub fn fd_pwrite(
wasi_ctx: &WasiCtx,
memory: &mut [u8],
@@ -147,6 +151,7 @@ pub fn fd_pwrite(
.unwrap_or_else(|e| e)
}
#[wasi_common_cbindgen]
pub fn fd_read(
wasi_ctx: &mut WasiCtx,
memory: &mut [u8],
@@ -189,6 +194,7 @@ pub fn fd_read(
.unwrap_or_else(|e| e)
}
#[wasi_common_cbindgen]
pub fn fd_renumber(
wasi_ctx: &mut WasiCtx,
from: wasm32::__wasi_fd_t,
@@ -213,6 +219,7 @@ pub fn fd_renumber(
wasm32::__WASI_ESUCCESS
}
#[wasi_common_cbindgen]
pub fn fd_seek(
wasi_ctx: &WasiCtx,
memory: &mut [u8],
@@ -253,6 +260,7 @@ pub fn fd_seek(
.unwrap_or_else(|e| e)
}
#[wasi_common_cbindgen]
pub fn fd_tell(
wasi_ctx: &WasiCtx,
memory: &mut [u8],
@@ -279,6 +287,7 @@ pub fn fd_tell(
.unwrap_or_else(|e| e)
}
#[wasi_common_cbindgen]
pub fn fd_fdstat_get(
wasi_ctx: &WasiCtx,
memory: &mut [u8],
@@ -313,6 +322,7 @@ pub fn fd_fdstat_get(
errno
}
#[wasi_common_cbindgen]
pub fn fd_fdstat_set_flags(
wasi_ctx: &WasiCtx,
fd: wasm32::__wasi_fd_t,
@@ -332,6 +342,7 @@ pub fn fd_fdstat_set_flags(
}
}
#[wasi_common_cbindgen]
pub fn fd_fdstat_set_rights(
wasi_ctx: &mut WasiCtx,
fd: wasm32::__wasi_fd_t,
@@ -354,6 +365,7 @@ pub fn fd_fdstat_set_rights(
wasm32::__WASI_ESUCCESS
}
#[wasi_common_cbindgen]
pub fn fd_sync(wasi_ctx: &WasiCtx, fd: wasm32::__wasi_fd_t) -> wasm32::__wasi_errno_t {
let host_fd = dec_fd(fd);
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
}
#[wasi_common_cbindgen]
pub fn fd_write(
wasi_ctx: &WasiCtx,
memory: &mut [u8],
@@ -404,6 +417,7 @@ pub fn fd_write(
.unwrap_or_else(|e| e)
}
#[wasi_common_cbindgen]
pub fn fd_advise(
wasi_ctx: &WasiCtx,
fd: wasm32::__wasi_fd_t,
@@ -462,6 +476,7 @@ pub fn fd_advise(
wasm32::__WASI_ESUCCESS
}
#[wasi_common_cbindgen]
pub fn fd_allocate(
wasi_ctx: &WasiCtx,
fd: wasm32::__wasi_fd_t,
@@ -514,6 +529,7 @@ pub fn fd_allocate(
wasm32::__WASI_ESUCCESS
}
#[wasi_common_cbindgen]
pub fn path_create_directory(
wasi_ctx: &WasiCtx,
memory: &mut [u8],
@@ -552,6 +568,7 @@ pub fn path_create_directory(
}
}
#[wasi_common_cbindgen]
pub fn path_link(
wasi_ctx: &WasiCtx,
memory: &mut [u8],
@@ -613,6 +630,7 @@ pub fn path_link(
wasm32::__WASI_ESUCCESS
}
#[wasi_common_cbindgen]
pub fn path_open(
wasi_ctx: &mut WasiCtx,
memory: &mut [u8],
@@ -770,6 +788,7 @@ pub fn path_open(
.unwrap_or_else(|e| e)
}
#[wasi_common_cbindgen]
pub fn fd_readdir(
wasi_ctx: &WasiCtx,
memory: &mut [u8],
@@ -817,10 +836,11 @@ pub fn fd_readdir(
if host_entry.is_null() {
break;
}
let entry: wasm32::__wasi_dirent_t = match dirent_from_host(&unsafe { *host_entry }) {
Ok(entry) => entry,
Err(e) => return enc_errno(e),
};
let entry: wasm32::__wasi_dirent_t =
match host_impl::dirent_from_host(&unsafe { *host_entry }) {
Ok(entry) => entry,
Err(e) => return enc_errno(e),
};
let name_len = entry.d_namlen as usize;
let required_space = std::mem::size_of_val(&entry) + name_len;
if required_space > left {
@@ -849,6 +869,7 @@ pub fn fd_readdir(
.unwrap_or_else(|e| e)
}
#[wasi_common_cbindgen]
pub fn path_readlink(
wasi_ctx: &WasiCtx,
memory: &mut [u8],
@@ -892,6 +913,7 @@ pub fn path_readlink(
wasm32::__WASI_ESUCCESS
}
#[wasi_common_cbindgen]
pub fn path_rename(
wasi_ctx: &WasiCtx,
memory: &mut [u8],
@@ -948,6 +970,7 @@ pub fn path_rename(
wasm32::__WASI_ESUCCESS
}
#[wasi_common_cbindgen]
pub fn fd_filestat_get(
wasi_ctx: &WasiCtx,
memory: &mut [u8],
@@ -974,6 +997,7 @@ pub fn fd_filestat_get(
errno
}
#[wasi_common_cbindgen]
pub fn fd_filestat_set_times(
wasi_ctx: &WasiCtx,
fd: wasm32::__wasi_fd_t,
@@ -1030,6 +1054,7 @@ pub fn fd_filestat_set_times(
wasm32::__WASI_ESUCCESS
}
#[wasi_common_cbindgen]
pub fn fd_filestat_set_size(
wasi_ctx: &WasiCtx,
fd: wasm32::__wasi_fd_t,
@@ -1053,6 +1078,7 @@ pub fn fd_filestat_set_size(
wasm32::__WASI_ESUCCESS
}
#[wasi_common_cbindgen]
pub fn path_filestat_get(
wasi_ctx: &WasiCtx,
memory: &mut [u8],
@@ -1098,6 +1124,7 @@ pub fn path_filestat_get(
}
}
#[wasi_common_cbindgen]
pub fn path_filestat_set_times(
wasi_ctx: &WasiCtx,
memory: &mut [u8],
@@ -1171,6 +1198,7 @@ pub fn path_filestat_set_times(
wasm32::__WASI_ESUCCESS
}
#[wasi_common_cbindgen]
pub fn path_symlink(
wasi_ctx: &WasiCtx,
memory: &mut [u8],
@@ -1211,6 +1239,7 @@ pub fn path_symlink(
wasm32::__WASI_ESUCCESS
}
#[wasi_common_cbindgen]
pub fn path_unlink_file(
wasi_ctx: &WasiCtx,
memory: &mut [u8],
@@ -1249,6 +1278,7 @@ pub fn path_unlink_file(
}
}
#[wasi_common_cbindgen]
pub fn path_remove_directory(
wasi_ctx: &WasiCtx,
memory: &mut [u8],
@@ -1280,6 +1310,7 @@ pub fn path_remove_directory(
}
}
#[wasi_common_cbindgen]
pub fn fd_prestat_get(
wasi_ctx: &WasiCtx,
memory: &mut [u8],
@@ -1316,6 +1347,7 @@ pub fn fd_prestat_get(
}
}
#[wasi_common_cbindgen]
pub fn fd_prestat_dir_name(
wasi_ctx: &WasiCtx,
memory: &mut [u8],

View File

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

View File

@@ -1,15 +1,17 @@
#![allow(non_camel_case_types)]
#![allow(unused_unsafe)]
use super::host_impl;
use crate::memory::*;
use crate::{host, wasm32};
use crate::sys::host as host_impl;
use nix::convert_ioctl_res;
use nix::libc::{self, c_int};
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,
@@ -49,6 +51,7 @@ pub fn clock_res_get(
})
}
#[wasi_common_cbindgen]
pub fn clock_time_get(
memory: &mut [u8],
clock_id: wasm32::__wasi_clockid_t,
@@ -85,6 +88,7 @@ pub fn clock_time_get(
})
}
#[wasi_common_cbindgen]
pub fn poll_oneoff(
memory: &mut [u8],
input: wasm32::uintptr_t,
@@ -176,6 +180,7 @@ pub fn poll_oneoff(
wasm32::__WASI_ESUCCESS
}
#[wasi_common_cbindgen]
pub fn sched_yield() -> wasm32::__wasi_errno_t {
unsafe { libc::sched_yield() };
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).
mod fs;
mod fs_helpers;
mod misc;
mod sock;
use super::fdentry;
use super::host_impl;
pub use self::fs::*;
pub use self::misc::*;
pub use self::sock::*;

View File

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

View File

@@ -1,41 +1,6 @@
pub mod host;
pub mod fdentry;
mod host_impl;
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 {
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(unused_unsafe)]
#![allow(unused)]
use super::host_impl;
use super::host_impl::IoVec;
use crate::ctx::WasiCtx;
use crate::wasm32;
use crate::sys::hostcalls as hostcalls_impl;
use crate::memory::*;
use crate::{host, wasm32};
use std::cmp;
use std::os::windows::prelude::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 {
hostcalls_impl::fd_close(wasi_ctx, fd)
unimplemented!("fd_close")
}
#[wasi_common_cbindgen]
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]
@@ -26,7 +32,7 @@ pub fn fd_pread(
offset: wasm32::__wasi_filesize_t,
nread: wasm32::uintptr_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]
@@ -39,7 +45,7 @@ pub fn fd_pwrite(
offset: wasm32::__wasi_filesize_t,
nwritten: wasm32::uintptr_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]
@@ -51,7 +57,7 @@ pub fn fd_read(
iovs_len: wasm32::size_t,
nread: wasm32::uintptr_t,
) -> wasm32::__wasi_errno_t {
hostcalls_impl::fd_read(wasi_ctx, memory, fd, iovs_ptr, iovs_len, nread)
unimplemented!("fd_read")
}
#[wasi_common_cbindgen]
@@ -60,7 +66,7 @@ pub fn fd_renumber(
from: wasm32::__wasi_fd_t,
to: wasm32::__wasi_fd_t,
) -> wasm32::__wasi_errno_t {
hostcalls_impl::fd_renumber(wasi_ctx, from, to)
unimplemented!("fd_renumber")
}
#[wasi_common_cbindgen]
@@ -72,7 +78,7 @@ pub fn fd_seek(
whence: wasm32::__wasi_whence_t,
newoffset: wasm32::uintptr_t,
) -> wasm32::__wasi_errno_t {
hostcalls_impl::fd_seek(wasi_ctx, memory, fd, offset, whence, newoffset)
unimplemented!("fd_seek")
}
#[wasi_common_cbindgen]
@@ -82,7 +88,7 @@ pub fn fd_tell(
fd: wasm32::__wasi_fd_t,
newoffset: wasm32::uintptr_t,
) -> wasm32::__wasi_errno_t {
hostcalls_impl::fd_tell(wasi_ctx, memory, fd, newoffset)
unimplemented!("fd_tell")
}
#[wasi_common_cbindgen]
@@ -90,9 +96,9 @@ pub fn fd_fdstat_get(
wasi_ctx: &WasiCtx,
memory: &mut [u8],
fd: wasm32::__wasi_fd_t,
fdstat_ptr: wasm32::uintptr_t,
fdstat_ptr: wasm32::uintptr_t, // *mut wasm32::__wasi_fdstat_t
) -> wasm32::__wasi_errno_t {
hostcalls_impl::fd_fdstat_get(wasi_ctx, memory, fd, fdstat_ptr)
unimplemented!("fd_fdstat_get")
}
#[wasi_common_cbindgen]
@@ -101,7 +107,7 @@ pub fn fd_fdstat_set_flags(
fd: wasm32::__wasi_fd_t,
fdflags: wasm32::__wasi_fdflags_t,
) -> wasm32::__wasi_errno_t {
hostcalls_impl::fd_fdstat_set_flags(wasi_ctx, fd, fdflags)
unimplemented!("fd_fdstat_set_flags")
}
#[wasi_common_cbindgen]
@@ -111,12 +117,12 @@ pub fn fd_fdstat_set_rights(
fs_rights_base: wasm32::__wasi_rights_t,
fs_rights_inheriting: wasm32::__wasi_rights_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]
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]
@@ -128,7 +134,46 @@ pub fn fd_write(
iovs_len: wasm32::size_t,
nwritten: wasm32::uintptr_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]
@@ -139,7 +184,7 @@ pub fn fd_advise(
len: wasm32::__wasi_filesize_t,
advice: wasm32::__wasi_advice_t,
) -> wasm32::__wasi_errno_t {
hostcalls_impl::fd_advise(wasi_ctx, fd, offset, len, advice)
unimplemented!("fd_advise")
}
#[wasi_common_cbindgen]
@@ -149,7 +194,7 @@ pub fn fd_allocate(
offset: wasm32::__wasi_filesize_t,
len: wasm32::__wasi_filesize_t,
) -> wasm32::__wasi_errno_t {
hostcalls_impl::fd_allocate(wasi_ctx, fd, offset, len)
unimplemented!("fd_allocate")
}
#[wasi_common_cbindgen]
@@ -160,7 +205,7 @@ pub fn path_create_directory(
path_ptr: wasm32::uintptr_t,
path_len: wasm32::size_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]
@@ -168,24 +213,14 @@ pub fn path_link(
wasi_ctx: &WasiCtx,
memory: &mut [u8],
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_len: wasm32::size_t,
new_dirfd: wasm32::__wasi_fd_t,
new_path_ptr: wasm32::uintptr_t,
new_path_len: wasm32::size_t,
) -> wasm32::__wasi_errno_t {
hostcalls_impl::path_link(
wasi_ctx,
memory,
old_dirfd,
old_flags,
old_path_ptr,
old_path_len,
new_dirfd,
new_path_ptr,
new_path_len,
)
unimplemented!("path_link")
}
#[wasi_common_cbindgen]
@@ -202,19 +237,7 @@ pub fn path_open(
fs_flags: wasm32::__wasi_fdflags_t,
fd_out_ptr: wasm32::uintptr_t,
) -> wasm32::__wasi_errno_t {
hostcalls_impl::path_open(
wasi_ctx,
memory,
dirfd,
dirflags,
path_ptr,
path_len,
oflags,
fs_rights_base,
fs_rights_inheriting,
fs_flags,
fd_out_ptr,
)
unimplemented!("path_open")
}
#[wasi_common_cbindgen]
@@ -227,7 +250,7 @@ pub fn fd_readdir(
cookie: wasm32::__wasi_dircookie_t,
buf_used: wasm32::uintptr_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]
@@ -241,9 +264,7 @@ pub fn path_readlink(
buf_len: wasm32::size_t,
buf_used: wasm32::uintptr_t,
) -> wasm32::__wasi_errno_t {
hostcalls_impl::path_readlink(
wasi_ctx, memory, dirfd, path_ptr, path_len, buf_ptr, buf_len, buf_used,
)
unimplemented!("path_readlink")
}
#[wasi_common_cbindgen]
@@ -257,16 +278,7 @@ pub fn path_rename(
new_path_ptr: wasm32::uintptr_t,
new_path_len: wasm32::size_t,
) -> wasm32::__wasi_errno_t {
hostcalls_impl::path_rename(
wasi_ctx,
memory,
old_dirfd,
old_path_ptr,
old_path_len,
new_dirfd,
new_path_ptr,
new_path_len,
)
unimplemented!("path_rename")
}
#[wasi_common_cbindgen]
@@ -276,7 +288,7 @@ pub fn fd_filestat_get(
fd: wasm32::__wasi_fd_t,
filestat_ptr: wasm32::uintptr_t,
) -> wasm32::__wasi_errno_t {
hostcalls_impl::fd_filestat_get(wasi_ctx, memory, fd, filestat_ptr)
unimplemented!("fd_filestat_get")
}
#[wasi_common_cbindgen]
@@ -287,7 +299,7 @@ pub fn fd_filestat_set_times(
st_mtim: wasm32::__wasi_timestamp_t,
fst_flags: wasm32::__wasi_fstflags_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]
@@ -296,7 +308,7 @@ pub fn fd_filestat_set_size(
fd: wasm32::__wasi_fd_t,
st_size: wasm32::__wasi_filesize_t,
) -> wasm32::__wasi_errno_t {
hostcalls_impl::fd_filestat_set_size(wasi_ctx, fd, st_size)
unimplemented!("fd_filestat_set_size")
}
#[wasi_common_cbindgen]
@@ -309,15 +321,7 @@ pub fn path_filestat_get(
path_len: wasm32::size_t,
filestat_ptr: wasm32::uintptr_t,
) -> wasm32::__wasi_errno_t {
hostcalls_impl::path_filestat_get(
wasi_ctx,
memory,
dirfd,
dirflags,
path_ptr,
path_len,
filestat_ptr,
)
unimplemented!("path_filestat_get")
}
#[wasi_common_cbindgen]
@@ -332,9 +336,7 @@ pub fn path_filestat_set_times(
st_mtim: wasm32::__wasi_timestamp_t,
fst_flags: wasm32::__wasi_fstflags_t,
) -> wasm32::__wasi_errno_t {
hostcalls_impl::path_filestat_set_times(
wasi_ctx, memory, dirfd, dirflags, path_ptr, path_len, st_atim, st_mtim, fst_flags,
)
unimplemented!("path_filestat_set_times")
}
#[wasi_common_cbindgen]
@@ -347,15 +349,7 @@ pub fn path_symlink(
new_path_ptr: wasm32::uintptr_t,
new_path_len: wasm32::size_t,
) -> wasm32::__wasi_errno_t {
hostcalls_impl::path_symlink(
wasi_ctx,
memory,
old_path_ptr,
old_path_len,
dirfd,
new_path_ptr,
new_path_len,
)
unimplemented!("path_symlink")
}
#[wasi_common_cbindgen]
@@ -366,7 +360,7 @@ pub fn path_unlink_file(
path_ptr: wasm32::uintptr_t,
path_len: wasm32::size_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]
@@ -377,7 +371,7 @@ pub fn path_remove_directory(
path_ptr: wasm32::uintptr_t,
path_len: wasm32::size_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]
@@ -387,7 +381,35 @@ pub fn fd_prestat_get(
fd: wasm32::__wasi_fd_t,
prestat_ptr: wasm32::uintptr_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]
@@ -398,5 +420,33 @@ pub fn fd_prestat_dir_name(
path_ptr: wasm32::uintptr_t,
path_len: wasm32::size_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(unused_unsafe)]
#![allow(unused)]
use crate::ctx::WasiCtx;
use crate::wasm32;
use crate::sys::hostcalls as hostcalls_impl;
use wasi_common_cbindgen::wasi_common_cbindgen;
#[wasi_common_cbindgen]
@@ -17,16 +17,7 @@ pub fn sock_recv(
ro_datalen: wasm32::uintptr_t,
ro_flags: wasm32::uintptr_t,
) -> wasm32::__wasi_errno_t {
hostcalls_impl::sock_recv(
wasi_ctx,
memory,
sock,
ri_data,
ri_data_len,
ri_flags,
ro_datalen,
ro_flags,
)
unimplemented!("sock_recv")
}
#[wasi_common_cbindgen]
@@ -39,15 +30,7 @@ pub fn sock_send(
si_flags: wasm32::__wasi_siflags_t,
so_datalen: wasm32::uintptr_t,
) -> wasm32::__wasi_errno_t {
hostcalls_impl::sock_send(
wasi_ctx,
memory,
sock,
si_data,
si_data_len,
si_flags,
so_datalen,
)
unimplemented!("sock_send")
}
#[wasi_common_cbindgen]
@@ -57,5 +40,5 @@ pub fn sock_shutdown(
sock: wasm32::__wasi_fd_t,
how: wasm32::__wasi_sdflags_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")
}