Merge remote-tracking branch 'upstream/master' into poll
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "wasi-common"
|
||||
version = "0.7.0"
|
||||
version = "0.9.0"
|
||||
authors = ["The Wasmtime Project Developers"]
|
||||
description = "WASI implementation in Rust"
|
||||
license = "Apache-2.0 WITH LLVM-exception"
|
||||
@@ -11,7 +11,7 @@ readme = "README.md"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
wasi-common-cbindgen = { path = "wasi-common-cbindgen" }
|
||||
wasi-common-cbindgen = { path = "wasi-common-cbindgen", version = "0.9.0" }
|
||||
anyhow = "1.0"
|
||||
thiserror = "1.0"
|
||||
libc = "0.2"
|
||||
@@ -21,14 +21,14 @@ log = "0.4"
|
||||
filetime = "0.2.7"
|
||||
lazy_static = "1.4.0"
|
||||
num = { version = "0.2.0", default-features = false }
|
||||
wig = { path = "wig" }
|
||||
crossbeam = "0.7.3"
|
||||
wig = { path = "wig", version = "0.9.2" }
|
||||
|
||||
[target.'cfg(unix)'.dependencies]
|
||||
yanix = { path = "yanix" }
|
||||
yanix = { path = "yanix", version = "0.9.0" }
|
||||
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
winx = { path = "winx" }
|
||||
winx = { path = "winx", version = "0.9.0" }
|
||||
winapi = "0.3"
|
||||
cpu-time = "1.0"
|
||||
|
||||
|
||||
Submodule crates/wasi-common/WASI deleted from 9150e66a34
@@ -155,8 +155,21 @@ impl FdEntry {
|
||||
rights_base: wasi::__wasi_rights_t,
|
||||
rights_inheriting: wasi::__wasi_rights_t,
|
||||
) -> Result<()> {
|
||||
if !self.rights_base & rights_base != 0 || !self.rights_inheriting & rights_inheriting != 0
|
||||
{
|
||||
let missing_base = !self.rights_base & rights_base;
|
||||
let missing_inheriting = !self.rights_inheriting & rights_inheriting;
|
||||
if missing_base != 0 || missing_inheriting != 0 {
|
||||
log::trace!(
|
||||
" | validate_rights failed: required: \
|
||||
rights_base = {:#x}, rights_inheriting = {:#x}; \
|
||||
actual: rights_base = {:#x}, rights_inheriting = {:#x}; \
|
||||
missing_base = {:#x}, missing_inheriting = {:#x}",
|
||||
rights_base,
|
||||
rights_inheriting,
|
||||
self.rights_base,
|
||||
self.rights_inheriting,
|
||||
missing_base,
|
||||
missing_inheriting
|
||||
);
|
||||
Err(Error::ENOTCAPABLE)
|
||||
} else {
|
||||
Ok(())
|
||||
|
||||
@@ -67,7 +67,7 @@ hostcalls! {
|
||||
) -> wasi::__wasi_errno_t;
|
||||
|
||||
pub unsafe fn fd_fdstat_set_flags(
|
||||
wasi_ctx: &WasiCtx,
|
||||
wasi_ctx: &mut WasiCtx,
|
||||
memory: &mut [u8],
|
||||
fd: wasi::__wasi_fd_t,
|
||||
fdflags: wasi::__wasi_fdflags_t,
|
||||
|
||||
@@ -5,7 +5,6 @@ use crate::fdentry::{Descriptor, FdEntry};
|
||||
use crate::helpers::*;
|
||||
use crate::memory::*;
|
||||
use crate::sandboxed_tty_writer::SandboxedTTYWriter;
|
||||
use crate::sys::fdentry_impl::determine_type_rights;
|
||||
use crate::sys::hostcalls_impl::fs_helpers::path_open_rights;
|
||||
use crate::sys::{host_impl, hostcalls_impl};
|
||||
use crate::{helpers, host, wasi, wasi32, Error, Result};
|
||||
@@ -299,19 +298,24 @@ pub(crate) unsafe fn fd_fdstat_get(
|
||||
}
|
||||
|
||||
pub(crate) unsafe fn fd_fdstat_set_flags(
|
||||
wasi_ctx: &WasiCtx,
|
||||
wasi_ctx: &mut WasiCtx,
|
||||
_memory: &mut [u8],
|
||||
fd: wasi::__wasi_fd_t,
|
||||
fdflags: wasi::__wasi_fdflags_t,
|
||||
) -> Result<()> {
|
||||
trace!("fd_fdstat_set_flags(fd={:?}, fdflags={:#x?})", fd, fdflags);
|
||||
|
||||
let fd = wasi_ctx
|
||||
.get_fd_entry(fd)?
|
||||
.as_descriptor(0, 0)?
|
||||
.as_os_handle();
|
||||
let descriptor = wasi_ctx
|
||||
.get_fd_entry_mut(fd)?
|
||||
.as_descriptor_mut(wasi::__WASI_RIGHTS_FD_FDSTAT_SET_FLAGS, 0)?;
|
||||
|
||||
hostcalls_impl::fd_fdstat_set_flags(&fd, fdflags)
|
||||
if let Some(new_handle) =
|
||||
hostcalls_impl::fd_fdstat_set_flags(&descriptor.as_os_handle(), fdflags)?
|
||||
{
|
||||
*descriptor = Descriptor::OsHandle(new_handle);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) unsafe fn fd_fdstat_set_rights(
|
||||
@@ -574,6 +578,11 @@ pub(crate) unsafe fn path_open(
|
||||
|
||||
let (needed_base, needed_inheriting) =
|
||||
path_open_rights(fs_rights_base, fs_rights_inheriting, oflags, fs_flags);
|
||||
trace!(
|
||||
" | needed_base = {}, needed_inheriting = {}",
|
||||
needed_base,
|
||||
needed_inheriting
|
||||
);
|
||||
let fe = wasi_ctx.get_fd_entry(dirfd)?;
|
||||
let resolved = path_get(
|
||||
fe,
|
||||
@@ -593,13 +602,20 @@ pub(crate) unsafe fn path_open(
|
||||
| wasi::__WASI_RIGHTS_FD_FILESTAT_SET_SIZE)
|
||||
!= 0;
|
||||
|
||||
trace!(
|
||||
" | calling path_open impl: read={}, write={}",
|
||||
read,
|
||||
write
|
||||
);
|
||||
let fd = hostcalls_impl::path_open(resolved, read, write, oflags, fs_flags)?;
|
||||
|
||||
// Determine the type of the new file descriptor and which rights contradict with this type
|
||||
let (_ty, max_base, max_inheriting) = determine_type_rights(&fd)?;
|
||||
let mut fe = FdEntry::from(fd)?;
|
||||
fe.rights_base &= max_base;
|
||||
fe.rights_inheriting &= max_inheriting;
|
||||
// We need to manually deny the rights which are not explicitly requested.
|
||||
// This should not be needed, but currently determine_type_and_access_rights,
|
||||
// which is used by FdEntry::from, may grant extra rights while inferring it
|
||||
// from the open mode.
|
||||
fe.rights_base &= fs_rights_base;
|
||||
fe.rights_inheriting &= fs_rights_inheriting;
|
||||
let guest_fd = wasi_ctx.insert_fd_entry(fe)?;
|
||||
|
||||
trace!(" | *fd={:?}", guest_fd);
|
||||
@@ -709,7 +725,10 @@ pub(crate) unsafe fn fd_filestat_get(
|
||||
filestat_ptr
|
||||
);
|
||||
|
||||
let fd = wasi_ctx.get_fd_entry(fd)?.as_descriptor(0, 0)?.as_file()?;
|
||||
let fd = wasi_ctx
|
||||
.get_fd_entry(fd)?
|
||||
.as_descriptor(wasi::__WASI_RIGHTS_FD_FILESTAT_GET, 0)?
|
||||
.as_file()?;
|
||||
let host_filestat = hostcalls_impl::fd_filestat_get(fd)?;
|
||||
|
||||
trace!(" | *filestat_ptr={:?}", host_filestat);
|
||||
|
||||
@@ -242,9 +242,9 @@ pub(crate) fn poll_oneoff(
|
||||
{
|
||||
let wasi_fd = unsafe { subscription.u.fd_readwrite.file_descriptor };
|
||||
let rights = if r#type == wasi::__WASI_EVENTTYPE_FD_READ {
|
||||
wasi::__WASI_RIGHTS_FD_READ
|
||||
wasi::__WASI_RIGHTS_FD_READ | wasi::__WASI_RIGHTS_POLL_FD_READWRITE
|
||||
} else {
|
||||
wasi::__WASI_RIGHTS_FD_WRITE
|
||||
wasi::__WASI_RIGHTS_FD_WRITE | wasi::__WASI_RIGHTS_POLL_FD_READWRITE
|
||||
};
|
||||
|
||||
match unsafe {
|
||||
|
||||
@@ -29,9 +29,14 @@ pub(crate) fn fd_fdstat_get(fd: &File) -> Result<wasi::__wasi_fdflags_t> {
|
||||
.map_err(Into::into)
|
||||
}
|
||||
|
||||
pub(crate) fn fd_fdstat_set_flags(fd: &File, fdflags: wasi::__wasi_fdflags_t) -> Result<()> {
|
||||
pub(crate) fn fd_fdstat_set_flags(
|
||||
fd: &File,
|
||||
fdflags: wasi::__wasi_fdflags_t,
|
||||
) -> Result<Option<OsHandle>> {
|
||||
let nix_flags = host_impl::nix_from_fdflags(fdflags);
|
||||
unsafe { yanix::fcntl::set_status_flags(fd.as_raw_fd(), nix_flags) }.map_err(Into::into)
|
||||
unsafe { yanix::fcntl::set_status_flags(fd.as_raw_fd(), nix_flags) }
|
||||
.map(|_| None)
|
||||
.map_err(Into::into)
|
||||
}
|
||||
|
||||
pub(crate) fn fd_advise(
|
||||
|
||||
@@ -5,7 +5,7 @@ use crate::ctx::WasiCtx;
|
||||
use crate::fdentry::FdEntry;
|
||||
use crate::host::{Dirent, FileType};
|
||||
use crate::hostcalls_impl::{fd_filestat_set_times_impl, PathGet};
|
||||
use crate::sys::fdentry_impl::determine_type_rights;
|
||||
use crate::sys::fdentry_impl::{determine_type_rights, OsHandle};
|
||||
use crate::sys::host_impl::{self, path_from_host};
|
||||
use crate::sys::hostcalls_impl::fs_helpers::PathGetExt;
|
||||
use crate::{wasi, Error, Result};
|
||||
@@ -78,8 +78,26 @@ pub(crate) fn fd_fdstat_get(fd: &File) -> Result<wasi::__wasi_fdflags_t> {
|
||||
Ok(fdflags)
|
||||
}
|
||||
|
||||
pub(crate) fn fd_fdstat_set_flags(fd: &File, fdflags: wasi::__wasi_fdflags_t) -> Result<()> {
|
||||
unimplemented!("fd_fdstat_set_flags")
|
||||
pub(crate) fn fd_fdstat_set_flags(
|
||||
fd: &File,
|
||||
fdflags: wasi::__wasi_fdflags_t,
|
||||
) -> Result<Option<OsHandle>> {
|
||||
let handle = unsafe { fd.as_raw_handle() };
|
||||
|
||||
let access_mode = winx::file::query_access_information(handle)?;
|
||||
|
||||
let new_access_mode = file_access_mode_from_fdflags(
|
||||
fdflags,
|
||||
access_mode.contains(AccessMode::FILE_READ_DATA),
|
||||
access_mode.contains(AccessMode::FILE_WRITE_DATA)
|
||||
| access_mode.contains(AccessMode::FILE_APPEND_DATA),
|
||||
);
|
||||
|
||||
unsafe {
|
||||
Ok(Some(OsHandle::from(File::from_raw_handle(
|
||||
winx::file::reopen_file(handle, new_access_mode, file_flags_from_fdflags(fdflags))?,
|
||||
))))
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn fd_advise(
|
||||
@@ -119,9 +137,20 @@ pub(crate) fn path_open(
|
||||
) -> Result<File> {
|
||||
use winx::file::{AccessMode, CreationDisposition, Flags};
|
||||
|
||||
let is_trunc = oflags & wasi::__WASI_OFLAGS_TRUNC != 0;
|
||||
|
||||
if is_trunc {
|
||||
// Windows does not support append mode when opening for truncation
|
||||
// This is because truncation requires `GENERIC_WRITE` access, which will override the removal
|
||||
// of the `FILE_WRITE_DATA` permission.
|
||||
if fdflags & wasi::__WASI_FDFLAGS_APPEND != 0 {
|
||||
return Err(Error::ENOTSUP);
|
||||
}
|
||||
}
|
||||
|
||||
// convert open flags
|
||||
// note: the calls to `write(true)` are to bypass an internal OpenOption check
|
||||
// the write flag will ultimately be ignored when `access_mode` is called below.
|
||||
// the write flag will ultimately be ignored when `access_mode` is calculated below.
|
||||
let mut opts = OpenOptions::new();
|
||||
match creation_disposition_from_oflags(oflags) {
|
||||
CreationDisposition::CREATE_ALWAYS => {
|
||||
@@ -168,7 +197,14 @@ pub(crate) fn path_open(
|
||||
},
|
||||
}
|
||||
|
||||
opts.access_mode(file_access_mode_from_fdflags(fdflags, read, write).bits())
|
||||
let mut access_mode = file_access_mode_from_fdflags(fdflags, read, write);
|
||||
|
||||
// Truncation requires the special `GENERIC_WRITE` bit set (this is why it doesn't work with append-only mode)
|
||||
if is_trunc {
|
||||
access_mode |= AccessMode::GENERIC_WRITE;
|
||||
}
|
||||
|
||||
opts.access_mode(access_mode.bits())
|
||||
.custom_flags(file_flags_from_fdflags(fdflags).bits())
|
||||
.open(&path)
|
||||
.map_err(Into::into)
|
||||
@@ -195,12 +231,15 @@ fn file_access_mode_from_fdflags(
|
||||
) -> AccessMode {
|
||||
let mut access_mode = AccessMode::READ_CONTROL;
|
||||
|
||||
// Note that `GENERIC_READ` and `GENERIC_WRITE` cannot be used to properly support append-only mode
|
||||
// The file-specific flags `FILE_GENERIC_READ` and `FILE_GENERIC_WRITE` are used here instead
|
||||
// These flags have the same semantic meaning for file objects, but allow removal of specific permissions (see below)
|
||||
if read {
|
||||
access_mode.insert(AccessMode::GENERIC_READ);
|
||||
access_mode.insert(AccessMode::FILE_GENERIC_READ);
|
||||
}
|
||||
|
||||
if write {
|
||||
access_mode.insert(AccessMode::GENERIC_WRITE);
|
||||
access_mode.insert(AccessMode::FILE_GENERIC_WRITE);
|
||||
}
|
||||
|
||||
// For append, grant the handle FILE_APPEND_DATA access but *not* FILE_WRITE_DATA.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "wasi-common-cbindgen"
|
||||
version = "0.7.0"
|
||||
version = "0.9.0"
|
||||
authors = ["Jakub Konka <kubkon@jakubkonka.com>"]
|
||||
description = "Interface generator utilities used by wasi-common"
|
||||
license = "Apache-2.0 WITH LLVM-exception"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "wig"
|
||||
version = "0.7.0"
|
||||
version = "0.9.2"
|
||||
authors = ["Dan Gohman <sunfish@mozilla.com>"]
|
||||
description = "WebAssembly Interface Generator"
|
||||
license = "Apache-2.0 WITH LLVM-exception"
|
||||
@@ -8,6 +8,7 @@ categories = ["wasm"]
|
||||
keywords = ["webassembly", "wasm"]
|
||||
repository = "https://github.com/bytecodealliance/wasmtime"
|
||||
edition = "2018"
|
||||
include = ["src/**/*", "LICENSE", "WASI"]
|
||||
|
||||
[lib]
|
||||
proc-macro = true
|
||||
@@ -19,7 +20,7 @@ heck = "0.3.1"
|
||||
# We include the WASI repo primarily for the witx files, but it's also useful
|
||||
# to use the witx parser it contains, rather than the witx crate from
|
||||
# crates.io, so that it always matches the version of the witx files.
|
||||
witx = { path = "../WASI/tools/witx" }
|
||||
witx = "0.6.0"
|
||||
|
||||
[badges]
|
||||
maintenance = { status = "actively-developed" }
|
||||
|
||||
1
crates/wasi-common/wig/WASI
Submodule
1
crates/wasi-common/wig/WASI
Submodule
Submodule crates/wasi-common/wig/WASI added at 04d4eba571
@@ -28,7 +28,7 @@ pub(crate) fn witx_path_from_args(args: TokenStream) -> (String, String) {
|
||||
|
||||
fn witx_path(phase: &str, id: &str) -> String {
|
||||
let root = env!("CARGO_MANIFEST_DIR");
|
||||
format!("{}/../WASI/phases/{}/witx/{}.witx", root, phase, id)
|
||||
format!("{}/WASI/phases/{}/witx/{}.witx", root, phase, id)
|
||||
}
|
||||
|
||||
// Convert a `Literal` holding a string literal into the `String`.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "winx"
|
||||
version = "0.7.0"
|
||||
version = "0.9.0"
|
||||
authors = ["Jakub Konka <kubkon@jakubkonka.com>"]
|
||||
description = "Windows API helper library"
|
||||
license = "Apache-2.0 WITH LLVM-exception"
|
||||
|
||||
@@ -434,3 +434,22 @@ pub fn query_mode_information(handle: RawHandle) -> Result<FileModeInformation>
|
||||
|
||||
Ok(FileModeInformation::from_bits_truncate(info.Mode))
|
||||
}
|
||||
|
||||
pub fn reopen_file(handle: RawHandle, access_mode: AccessMode, flags: Flags) -> Result<RawHandle> {
|
||||
// Files on Windows are opened with DELETE, READ, and WRITE share mode by default (see OpenOptions in stdlib)
|
||||
// This keeps the same share mode when reopening the file handle
|
||||
let new_handle = unsafe {
|
||||
winbase::ReOpenFile(
|
||||
handle,
|
||||
access_mode.bits(),
|
||||
winnt::FILE_SHARE_DELETE | winnt::FILE_SHARE_READ | winnt::FILE_SHARE_WRITE,
|
||||
flags.bits(),
|
||||
)
|
||||
};
|
||||
|
||||
if new_handle == winapi::um::handleapi::INVALID_HANDLE_VALUE {
|
||||
return Err(winerror::WinError::last());
|
||||
}
|
||||
|
||||
Ok(new_handle)
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "yanix"
|
||||
version = "0.1.0"
|
||||
version = "0.9.0"
|
||||
authors = ["The Wasmtime Project Developers"]
|
||||
description = "Yet Another Nix crate: a Unix API helper library"
|
||||
license = "Apache-2.0 WITH LLVM-exception"
|
||||
|
||||
Reference in New Issue
Block a user