Add support for wasi_snapshot_preview1. (#592)
* Add support for wasi_snapshot_preview1. This adds support for the new ABI, while preserving compatibility support for the old ABI. * Fix compilation on platforms where nlink_t isn't 64-bit. * rustfmt * Fix Windows build errors.
This commit is contained in:
@@ -46,9 +46,9 @@ pub(crate) unsafe fn determine_type_and_access_rights<Fd: AsRawFd>(
|
||||
let flags = OFlag::from_bits_truncate(flags_bits);
|
||||
let accmode = flags & OFlag::O_ACCMODE;
|
||||
if accmode == OFlag::O_RDONLY {
|
||||
rights_base &= !wasi::__WASI_RIGHT_FD_WRITE;
|
||||
rights_base &= !wasi::__WASI_RIGHTS_FD_WRITE;
|
||||
} else if accmode == OFlag::O_WRONLY {
|
||||
rights_base &= !wasi::__WASI_RIGHT_FD_READ;
|
||||
rights_base &= !wasi::__WASI_RIGHTS_FD_READ;
|
||||
}
|
||||
|
||||
Ok((file_type, rights_base, rights_inheriting))
|
||||
|
||||
@@ -109,19 +109,19 @@ pub(crate) fn errno_from_nix(errno: nix::errno::Errno) -> Error {
|
||||
pub(crate) fn nix_from_fdflags(fdflags: wasi::__wasi_fdflags_t) -> nix::fcntl::OFlag {
|
||||
use nix::fcntl::OFlag;
|
||||
let mut nix_flags = OFlag::empty();
|
||||
if fdflags & wasi::__WASI_FDFLAG_APPEND != 0 {
|
||||
if fdflags & wasi::__WASI_FDFLAGS_APPEND != 0 {
|
||||
nix_flags.insert(OFlag::O_APPEND);
|
||||
}
|
||||
if fdflags & wasi::__WASI_FDFLAG_DSYNC != 0 {
|
||||
if fdflags & wasi::__WASI_FDFLAGS_DSYNC != 0 {
|
||||
nix_flags.insert(OFlag::O_DSYNC);
|
||||
}
|
||||
if fdflags & wasi::__WASI_FDFLAG_NONBLOCK != 0 {
|
||||
if fdflags & wasi::__WASI_FDFLAGS_NONBLOCK != 0 {
|
||||
nix_flags.insert(OFlag::O_NONBLOCK);
|
||||
}
|
||||
if fdflags & wasi::__WASI_FDFLAG_RSYNC != 0 {
|
||||
if fdflags & wasi::__WASI_FDFLAGS_RSYNC != 0 {
|
||||
nix_flags.insert(O_RSYNC);
|
||||
}
|
||||
if fdflags & wasi::__WASI_FDFLAG_SYNC != 0 {
|
||||
if fdflags & wasi::__WASI_FDFLAGS_SYNC != 0 {
|
||||
nix_flags.insert(OFlag::O_SYNC);
|
||||
}
|
||||
nix_flags
|
||||
@@ -131,19 +131,19 @@ pub(crate) fn fdflags_from_nix(oflags: nix::fcntl::OFlag) -> wasi::__wasi_fdflag
|
||||
use nix::fcntl::OFlag;
|
||||
let mut fdflags = 0;
|
||||
if oflags.contains(OFlag::O_APPEND) {
|
||||
fdflags |= wasi::__WASI_FDFLAG_APPEND;
|
||||
fdflags |= wasi::__WASI_FDFLAGS_APPEND;
|
||||
}
|
||||
if oflags.contains(OFlag::O_DSYNC) {
|
||||
fdflags |= wasi::__WASI_FDFLAG_DSYNC;
|
||||
fdflags |= wasi::__WASI_FDFLAGS_DSYNC;
|
||||
}
|
||||
if oflags.contains(OFlag::O_NONBLOCK) {
|
||||
fdflags |= wasi::__WASI_FDFLAG_NONBLOCK;
|
||||
fdflags |= wasi::__WASI_FDFLAGS_NONBLOCK;
|
||||
}
|
||||
if oflags.contains(O_RSYNC) {
|
||||
fdflags |= wasi::__WASI_FDFLAG_RSYNC;
|
||||
fdflags |= wasi::__WASI_FDFLAGS_RSYNC;
|
||||
}
|
||||
if oflags.contains(OFlag::O_SYNC) {
|
||||
fdflags |= wasi::__WASI_FDFLAG_SYNC;
|
||||
fdflags |= wasi::__WASI_FDFLAGS_SYNC;
|
||||
}
|
||||
fdflags
|
||||
}
|
||||
@@ -151,16 +151,16 @@ pub(crate) fn fdflags_from_nix(oflags: nix::fcntl::OFlag) -> wasi::__wasi_fdflag
|
||||
pub(crate) fn nix_from_oflags(oflags: wasi::__wasi_oflags_t) -> nix::fcntl::OFlag {
|
||||
use nix::fcntl::OFlag;
|
||||
let mut nix_flags = OFlag::empty();
|
||||
if oflags & wasi::__WASI_O_CREAT != 0 {
|
||||
if oflags & wasi::__WASI_OFLAGS_CREAT != 0 {
|
||||
nix_flags.insert(OFlag::O_CREAT);
|
||||
}
|
||||
if oflags & wasi::__WASI_O_DIRECTORY != 0 {
|
||||
if oflags & wasi::__WASI_OFLAGS_DIRECTORY != 0 {
|
||||
nix_flags.insert(OFlag::O_DIRECTORY);
|
||||
}
|
||||
if oflags & wasi::__WASI_O_EXCL != 0 {
|
||||
if oflags & wasi::__WASI_OFLAGS_EXCL != 0 {
|
||||
nix_flags.insert(OFlag::O_EXCL);
|
||||
}
|
||||
if oflags & wasi::__WASI_O_TRUNC != 0 {
|
||||
if oflags & wasi::__WASI_OFLAGS_TRUNC != 0 {
|
||||
nix_flags.insert(OFlag::O_TRUNC);
|
||||
}
|
||||
nix_flags
|
||||
@@ -198,19 +198,19 @@ pub(crate) fn filestat_from_nix(
|
||||
let filetype = nix::sys::stat::SFlag::from_bits_truncate(filestat.st_mode);
|
||||
let dev = wasi::__wasi_device_t::try_from(filestat.st_dev)?;
|
||||
let ino = wasi::__wasi_inode_t::try_from(filestat.st_ino)?;
|
||||
let st_atim = filestat_to_timestamp(filestat.st_atime as u64, filestat.st_atime_nsec as u64)?;
|
||||
let st_ctim = filestat_to_timestamp(filestat.st_ctime as u64, filestat.st_ctime_nsec as u64)?;
|
||||
let st_mtim = filestat_to_timestamp(filestat.st_mtime as u64, filestat.st_mtime_nsec as u64)?;
|
||||
let atim = filestat_to_timestamp(filestat.st_atime as u64, filestat.st_atime_nsec as u64)?;
|
||||
let ctim = filestat_to_timestamp(filestat.st_ctime as u64, filestat.st_ctime_nsec as u64)?;
|
||||
let mtim = filestat_to_timestamp(filestat.st_mtime as u64, filestat.st_mtime_nsec as u64)?;
|
||||
|
||||
Ok(wasi::__wasi_filestat_t {
|
||||
st_dev: dev,
|
||||
st_ino: ino,
|
||||
st_nlink: filestat.st_nlink as wasi::__wasi_linkcount_t,
|
||||
st_size: filestat.st_size as wasi::__wasi_filesize_t,
|
||||
st_atim,
|
||||
st_ctim,
|
||||
st_mtim,
|
||||
st_filetype: filetype_from_nix(filetype).to_wasi(),
|
||||
dev,
|
||||
ino,
|
||||
nlink: wasi::__wasi_linkcount_t::from(filestat.st_nlink),
|
||||
size: filestat.st_size as wasi::__wasi_filesize_t,
|
||||
atim,
|
||||
ctim,
|
||||
mtim,
|
||||
filetype: filetype_from_nix(filetype).to_wasi(),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -240,7 +240,7 @@ pub(crate) fn dirent_filetype_from_host(
|
||||
/// Creates owned WASI path from OS string.
|
||||
///
|
||||
/// NB WASI spec requires OS string to be valid UTF-8. Otherwise,
|
||||
/// `__WASI_EILSEQ` error is returned.
|
||||
/// `__WASI_ERRNO_ILSEQ` error is returned.
|
||||
pub(crate) fn path_from_host<S: AsRef<OsStr>>(s: S) -> Result<String> {
|
||||
helpers::path_from_slice(s.as_ref().as_bytes()).map(String::from)
|
||||
}
|
||||
|
||||
@@ -217,14 +217,14 @@ pub(crate) fn fd_filestat_get_impl(file: &std::fs::File) -> Result<wasi::__wasi_
|
||||
|
||||
let metadata = file.metadata()?;
|
||||
Ok(wasi::__wasi_filestat_t {
|
||||
st_dev: metadata.dev(),
|
||||
st_ino: metadata.ino(),
|
||||
st_nlink: metadata.nlink().try_into()?, // u64 doesn't fit into u32
|
||||
st_size: metadata.len(),
|
||||
st_atim: systemtime_to_timestamp(metadata.accessed()?)?,
|
||||
st_ctim: metadata.ctime().try_into()?, // i64 doesn't fit into u64
|
||||
st_mtim: systemtime_to_timestamp(metadata.modified()?)?,
|
||||
st_filetype: filetype(file, &metadata)?.to_wasi(),
|
||||
dev: metadata.dev(),
|
||||
ino: metadata.ino(),
|
||||
nlink: metadata.nlink().try_into()?, // u64 doesn't fit into u32
|
||||
size: metadata.len(),
|
||||
atim: systemtime_to_timestamp(metadata.accessed()?)?,
|
||||
ctim: metadata.ctime().try_into()?, // i64 doesn't fit into u64
|
||||
mtim: systemtime_to_timestamp(metadata.modified()?)?,
|
||||
filetype: filetype(file, &metadata)?.to_wasi(),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -283,16 +283,16 @@ pub(crate) fn path_filestat_set_times(
|
||||
use super::super::filetime::*;
|
||||
use std::time::{Duration, UNIX_EPOCH};
|
||||
|
||||
let set_atim = fst_flags & wasi::__WASI_FILESTAT_SET_ATIM != 0;
|
||||
let set_atim_now = fst_flags & wasi::__WASI_FILESTAT_SET_ATIM_NOW != 0;
|
||||
let set_mtim = fst_flags & wasi::__WASI_FILESTAT_SET_MTIM != 0;
|
||||
let set_mtim_now = fst_flags & wasi::__WASI_FILESTAT_SET_MTIM_NOW != 0;
|
||||
let set_atim = fst_flags & wasi::__WASI_FSTFLAGS_ATIM != 0;
|
||||
let set_atim_now = fst_flags & wasi::__WASI_FSTFLAGS_ATIM_NOW != 0;
|
||||
let set_mtim = fst_flags & wasi::__WASI_FSTFLAGS_MTIM != 0;
|
||||
let set_mtim_now = fst_flags & wasi::__WASI_FSTFLAGS_MTIM_NOW != 0;
|
||||
|
||||
if (set_atim && set_atim_now) || (set_mtim && set_mtim_now) {
|
||||
return Err(Error::EINVAL);
|
||||
}
|
||||
|
||||
let symlink_nofollow = wasi::__WASI_LOOKUP_SYMLINK_FOLLOW != dirflags;
|
||||
let symlink_nofollow = wasi::__WASI_LOOKUPFLAGS_SYMLINK_FOLLOW != dirflags;
|
||||
let atim = if set_atim {
|
||||
let time = UNIX_EPOCH + Duration::from_nanos(st_atim);
|
||||
FileTime::FileTime(filetime::FileTime::from_system_time(time))
|
||||
|
||||
@@ -13,25 +13,25 @@ pub(crate) fn path_open_rights(
|
||||
use nix::fcntl::OFlag;
|
||||
|
||||
// which rights are needed on the dirfd?
|
||||
let mut needed_base = wasi::__WASI_RIGHT_PATH_OPEN;
|
||||
let mut needed_base = wasi::__WASI_RIGHTS_PATH_OPEN;
|
||||
let mut needed_inheriting = rights_base | rights_inheriting;
|
||||
|
||||
// convert open flags
|
||||
let oflags = host_impl::nix_from_oflags(oflags);
|
||||
if oflags.contains(OFlag::O_CREAT) {
|
||||
needed_base |= wasi::__WASI_RIGHT_PATH_CREATE_FILE;
|
||||
needed_base |= wasi::__WASI_RIGHTS_PATH_CREATE_FILE;
|
||||
}
|
||||
if oflags.contains(OFlag::O_TRUNC) {
|
||||
needed_base |= wasi::__WASI_RIGHT_PATH_FILESTAT_SET_SIZE;
|
||||
needed_base |= wasi::__WASI_RIGHTS_PATH_FILESTAT_SET_SIZE;
|
||||
}
|
||||
|
||||
// convert file descriptor flags
|
||||
let fdflags = host_impl::nix_from_fdflags(fs_flags);
|
||||
if fdflags.contains(OFlag::O_DSYNC) {
|
||||
needed_inheriting |= wasi::__WASI_RIGHT_FD_DATASYNC;
|
||||
needed_inheriting |= wasi::__WASI_RIGHTS_FD_DATASYNC;
|
||||
}
|
||||
if fdflags.intersects(host_impl::O_RSYNC | OFlag::O_SYNC) {
|
||||
needed_inheriting |= wasi::__WASI_RIGHT_FD_SYNC;
|
||||
needed_inheriting |= wasi::__WASI_RIGHTS_FD_SYNC;
|
||||
}
|
||||
|
||||
(needed_base, needed_inheriting)
|
||||
|
||||
@@ -9,10 +9,10 @@ use std::mem::MaybeUninit;
|
||||
fn wasi_clock_id_to_unix(clock_id: wasi::__wasi_clockid_t) -> Result<libc::clockid_t> {
|
||||
// convert the supported clocks to the libc types, or return EINVAL
|
||||
match clock_id {
|
||||
wasi::__WASI_CLOCK_REALTIME => Ok(libc::CLOCK_REALTIME),
|
||||
wasi::__WASI_CLOCK_MONOTONIC => Ok(libc::CLOCK_MONOTONIC),
|
||||
wasi::__WASI_CLOCK_PROCESS_CPUTIME_ID => Ok(libc::CLOCK_PROCESS_CPUTIME_ID),
|
||||
wasi::__WASI_CLOCK_THREAD_CPUTIME_ID => Ok(libc::CLOCK_THREAD_CPUTIME_ID),
|
||||
wasi::__WASI_CLOCKID_REALTIME => Ok(libc::CLOCK_REALTIME),
|
||||
wasi::__WASI_CLOCKID_MONOTONIC => Ok(libc::CLOCK_MONOTONIC),
|
||||
wasi::__WASI_CLOCKID_PROCESS_CPUTIME_ID => Ok(libc::CLOCK_PROCESS_CPUTIME_ID),
|
||||
wasi::__WASI_CLOCKID_THREAD_CPUTIME_ID => Ok(libc::CLOCK_THREAD_CPUTIME_ID),
|
||||
_ => Err(Error::EINVAL),
|
||||
}
|
||||
}
|
||||
@@ -129,8 +129,8 @@ fn poll_oneoff_handle_timeout_event(
|
||||
events.push(wasi::__wasi_event_t {
|
||||
userdata: timeout.userdata,
|
||||
r#type: wasi::__WASI_EVENTTYPE_CLOCK,
|
||||
error: wasi::__WASI_ESUCCESS,
|
||||
u: wasi::__wasi_event_u {
|
||||
error: wasi::__WASI_ERRNO_SUCCESS,
|
||||
u: wasi::__wasi_event_u_t {
|
||||
fd_readwrite: wasi::__wasi_event_fd_readwrite_t {
|
||||
nbytes: 0,
|
||||
flags: 0,
|
||||
@@ -166,11 +166,11 @@ fn poll_oneoff_handle_fd_event<'a>(
|
||||
wasi::__wasi_event_t {
|
||||
userdata: fd_event.userdata,
|
||||
r#type: fd_event.r#type,
|
||||
error: wasi::__WASI_EBADF,
|
||||
u: wasi::__wasi_event_u {
|
||||
error: wasi::__WASI_ERRNO_BADF,
|
||||
u: wasi::__wasi_event_u_t {
|
||||
fd_readwrite: wasi::__wasi_event_fd_readwrite_t {
|
||||
nbytes: 0,
|
||||
flags: wasi::__WASI_EVENT_FD_READWRITE_HANGUP,
|
||||
flags: wasi::__WASI_EVENTRWFLAGS_FD_READWRITE_HANGUP,
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -178,11 +178,11 @@ fn poll_oneoff_handle_fd_event<'a>(
|
||||
wasi::__wasi_event_t {
|
||||
userdata: fd_event.userdata,
|
||||
r#type: fd_event.r#type,
|
||||
error: wasi::__WASI_EIO,
|
||||
u: wasi::__wasi_event_u {
|
||||
error: wasi::__WASI_ERRNO_IO,
|
||||
u: wasi::__wasi_event_u_t {
|
||||
fd_readwrite: wasi::__wasi_event_fd_readwrite_t {
|
||||
nbytes: 0,
|
||||
flags: wasi::__WASI_EVENT_FD_READWRITE_HANGUP,
|
||||
flags: wasi::__WASI_EVENTRWFLAGS_FD_READWRITE_HANGUP,
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -190,11 +190,11 @@ fn poll_oneoff_handle_fd_event<'a>(
|
||||
wasi::__wasi_event_t {
|
||||
userdata: fd_event.userdata,
|
||||
r#type: fd_event.r#type,
|
||||
error: wasi::__WASI_ESUCCESS,
|
||||
u: wasi::__wasi_event_u {
|
||||
error: wasi::__WASI_ERRNO_SUCCESS,
|
||||
u: wasi::__wasi_event_u_t {
|
||||
fd_readwrite: wasi::__wasi_event_fd_readwrite_t {
|
||||
nbytes: 0,
|
||||
flags: wasi::__WASI_EVENT_FD_READWRITE_HANGUP,
|
||||
flags: wasi::__WASI_EVENTRWFLAGS_FD_READWRITE_HANGUP,
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -202,8 +202,8 @@ fn poll_oneoff_handle_fd_event<'a>(
|
||||
wasi::__wasi_event_t {
|
||||
userdata: fd_event.userdata,
|
||||
r#type: fd_event.r#type,
|
||||
error: wasi::__WASI_ESUCCESS,
|
||||
u: wasi::__wasi_event_u {
|
||||
error: wasi::__WASI_ERRNO_SUCCESS,
|
||||
u: wasi::__wasi_event_u_t {
|
||||
fd_readwrite: wasi::__wasi_event_fd_readwrite_t {
|
||||
nbytes: nbytes.try_into()?,
|
||||
flags: 0,
|
||||
|
||||
@@ -61,10 +61,10 @@ pub(crate) unsafe fn determine_type_and_access_rights<Handle: AsRawHandle>(
|
||||
wasi::__WASI_FILETYPE_DIRECTORY | wasi::__WASI_FILETYPE_REGULAR_FILE => {
|
||||
let mode = get_file_access_mode(handle.as_raw_handle())?;
|
||||
if mode.contains(AccessMode::FILE_GENERIC_READ) {
|
||||
rights_base |= wasi::__WASI_RIGHT_FD_READ;
|
||||
rights_base |= wasi::__WASI_RIGHTS_FD_READ;
|
||||
}
|
||||
if mode.contains(AccessMode::FILE_GENERIC_WRITE) {
|
||||
rights_base |= wasi::__WASI_RIGHT_FD_WRITE;
|
||||
rights_base |= wasi::__WASI_RIGHTS_FD_WRITE;
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
|
||||
@@ -13,30 +13,30 @@ pub(crate) fn errno_from_win(error: winx::winerror::WinError) -> wasi::__wasi_er
|
||||
// TODO: implement error mapping between Windows and WASI
|
||||
use winx::winerror::WinError::*;
|
||||
match error {
|
||||
ERROR_SUCCESS => wasi::__WASI_ESUCCESS,
|
||||
ERROR_BAD_ENVIRONMENT => wasi::__WASI_E2BIG,
|
||||
ERROR_FILE_NOT_FOUND => wasi::__WASI_ENOENT,
|
||||
ERROR_PATH_NOT_FOUND => wasi::__WASI_ENOENT,
|
||||
ERROR_TOO_MANY_OPEN_FILES => wasi::__WASI_ENFILE,
|
||||
ERROR_ACCESS_DENIED => wasi::__WASI_EACCES,
|
||||
ERROR_SHARING_VIOLATION => wasi::__WASI_EACCES,
|
||||
ERROR_PRIVILEGE_NOT_HELD => wasi::__WASI_ENOTCAPABLE, // TODO is this the correct mapping?
|
||||
ERROR_INVALID_HANDLE => wasi::__WASI_EBADF,
|
||||
ERROR_INVALID_NAME => wasi::__WASI_ENOENT,
|
||||
ERROR_NOT_ENOUGH_MEMORY => wasi::__WASI_ENOMEM,
|
||||
ERROR_OUTOFMEMORY => wasi::__WASI_ENOMEM,
|
||||
ERROR_DIR_NOT_EMPTY => wasi::__WASI_ENOTEMPTY,
|
||||
ERROR_NOT_READY => wasi::__WASI_EBUSY,
|
||||
ERROR_BUSY => wasi::__WASI_EBUSY,
|
||||
ERROR_NOT_SUPPORTED => wasi::__WASI_ENOTSUP,
|
||||
ERROR_FILE_EXISTS => wasi::__WASI_EEXIST,
|
||||
ERROR_BROKEN_PIPE => wasi::__WASI_EPIPE,
|
||||
ERROR_BUFFER_OVERFLOW => wasi::__WASI_ENAMETOOLONG,
|
||||
ERROR_NOT_A_REPARSE_POINT => wasi::__WASI_EINVAL,
|
||||
ERROR_NEGATIVE_SEEK => wasi::__WASI_EINVAL,
|
||||
ERROR_DIRECTORY => wasi::__WASI_ENOTDIR,
|
||||
ERROR_ALREADY_EXISTS => wasi::__WASI_EEXIST,
|
||||
_ => wasi::__WASI_ENOTSUP,
|
||||
ERROR_SUCCESS => wasi::__WASI_ERRNO_SUCCESS,
|
||||
ERROR_BAD_ENVIRONMENT => wasi::__WASI_ERRNO_2BIG,
|
||||
ERROR_FILE_NOT_FOUND => wasi::__WASI_ERRNO_NOENT,
|
||||
ERROR_PATH_NOT_FOUND => wasi::__WASI_ERRNO_NOENT,
|
||||
ERROR_TOO_MANY_OPEN_FILES => wasi::__WASI_ERRNO_NFILE,
|
||||
ERROR_ACCESS_DENIED => wasi::__WASI_ERRNO_ACCES,
|
||||
ERROR_SHARING_VIOLATION => wasi::__WASI_ERRNO_ACCES,
|
||||
ERROR_PRIVILEGE_NOT_HELD => wasi::__WASI_ERRNO_NOTCAPABLE, // TODO is this the correct mapping?
|
||||
ERROR_INVALID_HANDLE => wasi::__WASI_ERRNO_BADF,
|
||||
ERROR_INVALID_NAME => wasi::__WASI_ERRNO_NOENT,
|
||||
ERROR_NOT_ENOUGH_MEMORY => wasi::__WASI_ERRNO_NOMEM,
|
||||
ERROR_OUTOFMEMORY => wasi::__WASI_ERRNO_NOMEM,
|
||||
ERROR_DIR_NOT_EMPTY => wasi::__WASI_ERRNO_NOTEMPTY,
|
||||
ERROR_NOT_READY => wasi::__WASI_ERRNO_BUSY,
|
||||
ERROR_BUSY => wasi::__WASI_ERRNO_BUSY,
|
||||
ERROR_NOT_SUPPORTED => wasi::__WASI_ERRNO_NOTSUP,
|
||||
ERROR_FILE_EXISTS => wasi::__WASI_ERRNO_EXIST,
|
||||
ERROR_BROKEN_PIPE => wasi::__WASI_ERRNO_PIPE,
|
||||
ERROR_BUFFER_OVERFLOW => wasi::__WASI_ERRNO_NAMETOOLONG,
|
||||
ERROR_NOT_A_REPARSE_POINT => wasi::__WASI_ERRNO_INVAL,
|
||||
ERROR_NEGATIVE_SEEK => wasi::__WASI_ERRNO_INVAL,
|
||||
ERROR_DIRECTORY => wasi::__WASI_ERRNO_NOTDIR,
|
||||
ERROR_ALREADY_EXISTS => wasi::__WASI_ERRNO_EXIST,
|
||||
_ => wasi::__WASI_ERRNO_NOTSUP,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,12 +44,12 @@ pub(crate) fn fdflags_from_win(mode: AccessMode) -> wasi::__wasi_fdflags_t {
|
||||
let mut fdflags = 0;
|
||||
// TODO verify this!
|
||||
if mode.contains(AccessMode::FILE_APPEND_DATA) {
|
||||
fdflags |= wasi::__WASI_FDFLAG_APPEND;
|
||||
fdflags |= wasi::__WASI_FDFLAGS_APPEND;
|
||||
}
|
||||
if mode.contains(AccessMode::SYNCHRONIZE) {
|
||||
fdflags |= wasi::__WASI_FDFLAG_DSYNC;
|
||||
fdflags |= wasi::__WASI_FDFLAG_RSYNC;
|
||||
fdflags |= wasi::__WASI_FDFLAG_SYNC;
|
||||
fdflags |= wasi::__WASI_FDFLAGS_DSYNC;
|
||||
fdflags |= wasi::__WASI_FDFLAGS_RSYNC;
|
||||
fdflags |= wasi::__WASI_FDFLAGS_SYNC;
|
||||
}
|
||||
// The NONBLOCK equivalent is FILE_FLAG_OVERLAPPED
|
||||
// but it seems winapi doesn't provide a mechanism
|
||||
@@ -68,15 +68,15 @@ pub(crate) fn win_from_fdflags(fdflags: wasi::__wasi_fdflags_t) -> (AccessMode,
|
||||
let mut flags = Flags::empty();
|
||||
|
||||
// TODO verify this!
|
||||
if fdflags & wasi::__WASI_FDFLAG_NONBLOCK != 0 {
|
||||
if fdflags & wasi::__WASI_FDFLAGS_NONBLOCK != 0 {
|
||||
flags.insert(Flags::FILE_FLAG_OVERLAPPED);
|
||||
}
|
||||
if fdflags & wasi::__WASI_FDFLAG_APPEND != 0 {
|
||||
if fdflags & wasi::__WASI_FDFLAGS_APPEND != 0 {
|
||||
access_mode.insert(AccessMode::FILE_APPEND_DATA);
|
||||
}
|
||||
if fdflags & wasi::__WASI_FDFLAG_DSYNC != 0
|
||||
|| fdflags & wasi::__WASI_FDFLAG_RSYNC != 0
|
||||
|| fdflags & wasi::__WASI_FDFLAG_SYNC != 0
|
||||
if fdflags & wasi::__WASI_FDFLAGS_DSYNC != 0
|
||||
|| fdflags & wasi::__WASI_FDFLAGS_RSYNC != 0
|
||||
|| fdflags & wasi::__WASI_FDFLAGS_SYNC != 0
|
||||
{
|
||||
access_mode.insert(AccessMode::SYNCHRONIZE);
|
||||
}
|
||||
@@ -85,13 +85,13 @@ pub(crate) fn win_from_fdflags(fdflags: wasi::__wasi_fdflags_t) -> (AccessMode,
|
||||
}
|
||||
|
||||
pub(crate) fn win_from_oflags(oflags: wasi::__wasi_oflags_t) -> CreationDisposition {
|
||||
if oflags & wasi::__WASI_O_CREAT != 0 {
|
||||
if oflags & wasi::__WASI_O_EXCL != 0 {
|
||||
if oflags & wasi::__WASI_OFLAGS_CREAT != 0 {
|
||||
if oflags & wasi::__WASI_OFLAGS_EXCL != 0 {
|
||||
CreationDisposition::CREATE_NEW
|
||||
} else {
|
||||
CreationDisposition::CREATE_ALWAYS
|
||||
}
|
||||
} else if oflags & wasi::__WASI_O_TRUNC != 0 {
|
||||
} else if oflags & wasi::__WASI_OFLAGS_TRUNC != 0 {
|
||||
CreationDisposition::TRUNCATE_EXISTING
|
||||
} else {
|
||||
CreationDisposition::OPEN_EXISTING
|
||||
@@ -101,7 +101,7 @@ pub(crate) fn win_from_oflags(oflags: wasi::__wasi_oflags_t) -> CreationDisposit
|
||||
/// Creates owned WASI path from OS string.
|
||||
///
|
||||
/// NB WASI spec requires OS string to be valid UTF-8. Otherwise,
|
||||
/// `__WASI_EILSEQ` error is returned.
|
||||
/// `__WASI_ERRNO_ILSEQ` error is returned.
|
||||
pub(crate) fn path_from_host<S: AsRef<OsStr>>(s: S) -> Result<String> {
|
||||
let vec: Vec<u16> = s.as_ref().encode_wide().collect();
|
||||
String::from_utf16(&vec).map_err(|_| Error::EILSEQ)
|
||||
|
||||
@@ -139,7 +139,7 @@ pub(crate) fn path_open(
|
||||
return Err(Error::ELOOP);
|
||||
}
|
||||
// check if we are trying to open a file as a dir
|
||||
if file_type.is_file() && oflags & wasi::__WASI_O_DIRECTORY != 0 {
|
||||
if file_type.is_file() && oflags & wasi::__WASI_OFLAGS_DIRECTORY != 0 {
|
||||
return Err(Error::ENOTDIR);
|
||||
}
|
||||
}
|
||||
@@ -410,14 +410,14 @@ pub(crate) fn change_time(file: &File, _metadata: &Metadata) -> io::Result<i64>
|
||||
pub(crate) fn fd_filestat_get_impl(file: &std::fs::File) -> Result<wasi::__wasi_filestat_t> {
|
||||
let metadata = file.metadata()?;
|
||||
Ok(wasi::__wasi_filestat_t {
|
||||
st_dev: device_id(file, &metadata)?,
|
||||
st_ino: file_serial_no(file)?,
|
||||
st_nlink: num_hardlinks(file, &metadata)?.try_into()?, // u64 doesn't fit into u32
|
||||
st_size: metadata.len(),
|
||||
st_atim: systemtime_to_timestamp(metadata.accessed()?)?,
|
||||
st_ctim: change_time(file, &metadata)?.try_into()?, // i64 doesn't fit into u64
|
||||
st_mtim: systemtime_to_timestamp(metadata.modified()?)?,
|
||||
st_filetype: filetype_from_std(&metadata.file_type()).to_wasi(),
|
||||
dev: device_id(file, &metadata)?,
|
||||
ino: file_serial_no(file)?,
|
||||
nlink: num_hardlinks(file, &metadata)?.try_into()?, // u64 doesn't fit into u32
|
||||
size: metadata.len(),
|
||||
atim: systemtime_to_timestamp(metadata.accessed()?)?,
|
||||
ctim: change_time(file, &metadata)?.try_into()?, // i64 doesn't fit into u64
|
||||
mtim: systemtime_to_timestamp(metadata.modified()?)?,
|
||||
filetype: filetype_from_std(&metadata.file_type()).to_wasi(),
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -23,23 +23,23 @@ pub(crate) fn path_open_rights(
|
||||
fdflags: wasi::__wasi_fdflags_t,
|
||||
) -> (wasi::__wasi_rights_t, wasi::__wasi_rights_t) {
|
||||
// which rights are needed on the dirfd?
|
||||
let mut needed_base = wasi::__WASI_RIGHT_PATH_OPEN;
|
||||
let mut needed_base = wasi::__WASI_RIGHTS_PATH_OPEN;
|
||||
let mut needed_inheriting = rights_base | rights_inheriting;
|
||||
|
||||
// convert open flags
|
||||
if oflags & wasi::__WASI_O_CREAT != 0 {
|
||||
needed_base |= wasi::__WASI_RIGHT_PATH_CREATE_FILE;
|
||||
} else if oflags & wasi::__WASI_O_TRUNC != 0 {
|
||||
needed_base |= wasi::__WASI_RIGHT_PATH_FILESTAT_SET_SIZE;
|
||||
if oflags & wasi::__WASI_OFLAGS_CREAT != 0 {
|
||||
needed_base |= wasi::__WASI_RIGHTS_PATH_CREATE_FILE;
|
||||
} else if oflags & wasi::__WASI_OFLAGS_TRUNC != 0 {
|
||||
needed_base |= wasi::__WASI_RIGHTS_PATH_FILESTAT_SET_SIZE;
|
||||
}
|
||||
|
||||
// convert file descriptor flags
|
||||
if fdflags & wasi::__WASI_FDFLAG_DSYNC != 0
|
||||
|| fdflags & wasi::__WASI_FDFLAG_RSYNC != 0
|
||||
|| fdflags & wasi::__WASI_FDFLAG_SYNC != 0
|
||||
if fdflags & wasi::__WASI_FDFLAGS_DSYNC != 0
|
||||
|| fdflags & wasi::__WASI_FDFLAGS_RSYNC != 0
|
||||
|| fdflags & wasi::__WASI_FDFLAGS_SYNC != 0
|
||||
{
|
||||
needed_inheriting |= wasi::__WASI_RIGHT_FD_DATASYNC;
|
||||
needed_inheriting |= wasi::__WASI_RIGHT_FD_SYNC;
|
||||
needed_inheriting |= wasi::__WASI_RIGHTS_FD_DATASYNC;
|
||||
needed_inheriting |= wasi::__WASI_RIGHTS_FD_SYNC;
|
||||
}
|
||||
|
||||
(needed_base, needed_inheriting)
|
||||
|
||||
@@ -53,25 +53,25 @@ pub(crate) fn clock_res_get(clock_id: wasi::__wasi_clockid_t) -> Result<wasi::__
|
||||
// [4] https://www.codeproject.com/Tips/1011902/High-Resolution-Time-For-Windows
|
||||
// [5] https://stackoverflow.com/questions/7685762/windows-7-timing-functions-how-to-use-getsystemtimeadjustment-correctly
|
||||
// [6] https://bugs.python.org/issue19007
|
||||
wasi::__WASI_CLOCK_REALTIME => 55_000_000,
|
||||
wasi::__WASI_CLOCKID_REALTIME => 55_000_000,
|
||||
// std::time::Instant uses QueryPerformanceCounter & QueryPerformanceFrequency internally
|
||||
wasi::__WASI_CLOCK_MONOTONIC => *PERF_COUNTER_RES,
|
||||
wasi::__WASI_CLOCKID_MONOTONIC => *PERF_COUNTER_RES,
|
||||
// The best we can do is to hardcode the value from the docs.
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-getprocesstimes
|
||||
wasi::__WASI_CLOCK_PROCESS_CPUTIME_ID => 100,
|
||||
wasi::__WASI_CLOCKID_PROCESS_CPUTIME_ID => 100,
|
||||
// The best we can do is to hardcode the value from the docs.
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-getthreadtimes
|
||||
wasi::__WASI_CLOCK_THREAD_CPUTIME_ID => 100,
|
||||
wasi::__WASI_CLOCKID_THREAD_CPUTIME_ID => 100,
|
||||
_ => return Err(Error::EINVAL),
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn clock_time_get(clock_id: wasi::__wasi_clockid_t) -> Result<wasi::__wasi_timestamp_t> {
|
||||
let duration = match clock_id {
|
||||
wasi::__WASI_CLOCK_REALTIME => get_monotonic_time(),
|
||||
wasi::__WASI_CLOCK_MONOTONIC => get_realtime_time()?,
|
||||
wasi::__WASI_CLOCK_PROCESS_CPUTIME_ID => get_proc_cputime()?,
|
||||
wasi::__WASI_CLOCK_THREAD_CPUTIME_ID => get_thread_cputime()?,
|
||||
wasi::__WASI_CLOCKID_REALTIME => get_monotonic_time(),
|
||||
wasi::__WASI_CLOCKID_MONOTONIC => get_realtime_time()?,
|
||||
wasi::__WASI_CLOCKID_PROCESS_CPUTIME_ID => get_proc_cputime()?,
|
||||
wasi::__WASI_CLOCKID_THREAD_CPUTIME_ID => get_thread_cputime()?,
|
||||
_ => return Err(Error::EINVAL),
|
||||
};
|
||||
duration.as_nanos().try_into().map_err(Into::into)
|
||||
@@ -87,7 +87,7 @@ pub(crate) fn poll_oneoff(
|
||||
|
||||
fn get_monotonic_time() -> Duration {
|
||||
// We're circumventing the fact that we can't get a Duration from an Instant
|
||||
// The epoch of __WASI_CLOCK_MONOTONIC is undefined, so we fix a time point once
|
||||
// The epoch of __WASI_CLOCKID_MONOTONIC is undefined, so we fix a time point once
|
||||
// and count relative to this time point.
|
||||
//
|
||||
// The alternative would be to copy over the implementation of std::time::Instant
|
||||
|
||||
Reference in New Issue
Block a user