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,