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:
Dan Gohman
2019-11-18 22:07:16 -08:00
committed by GitHub
parent 39e57e3e9a
commit d645902620
83 changed files with 9928 additions and 803 deletions

View File

@@ -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))

View File

@@ -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)
}

View File

@@ -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))

View File

@@ -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)

View File

@@ -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,

View File

@@ -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;
}
}
_ => {

View File

@@ -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)

View File

@@ -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(),
})
}

View File

@@ -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)

View File

@@ -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