Update WASI to cap-std 0.25 and windows-sys. (#4302)

This updates to rustix 0.35.6, and updates wasi-common to use cap-std 0.25 and
windows-sys (instead of winapi).

Changes include:

 - Better error code mappings on Windows.
 - Fixes undefined references to `utimensat` on Darwin.
 - Fixes undefined references to `preadv64` and `pwritev64` on Android.
 - Updates to io-lifetimes 0.7, which matches the io_safety API in Rust.
 - y2038 bug fixes for 32-bit platforms
This commit is contained in:
Dan Gohman
2022-06-23 10:47:15 -07:00
committed by GitHub
parent 445cc87a06
commit fa36e86f2c
27 changed files with 317 additions and 186 deletions

View File

@@ -24,7 +24,7 @@ wasmtime-wasi = { path = "../wasi" }
wasmtime-wasi-crypto = { path = "../wasi-crypto", optional = true }
wasmtime-wasi-nn = { path = "../wasi-nn", optional = true }
wasi-cap-std-sync = { path = "../wasi-common/cap-std-sync" }
cap-std = "0.24.1"
cap-std = "0.25.0"
[dev-dependencies]
wat = "1.0"

View File

@@ -29,7 +29,7 @@ wat = { version = "1.0.42", optional = true }
# Optional dependencies for the `wasi` feature
wasi-cap-std-sync = { path = "../wasi-common/cap-std-sync", optional = true }
wasmtime-wasi = { path = "../wasi", optional = true }
cap-std = { version = "0.24.1", optional = true }
cap-std = { version = "0.25.0", optional = true }
[features]
default = ['jitdump', 'wat', 'wasi', 'cache', 'parallel-compilation']

View File

@@ -24,7 +24,7 @@ zstd = { version = "0.11.1", default-features = false }
winapi = "0.3.7"
[target.'cfg(not(target_os = "windows"))'.dependencies]
rustix = "0.33.7"
rustix = { version = "0.35.6", features = ["process"] }
[dev-dependencies]
filetime = "0.2.7"

View File

@@ -14,7 +14,7 @@ edition = "2021"
links = "wasmtime-fiber-shims"
[target.'cfg(unix)'.dependencies]
rustix = "0.33.7"
rustix = { version = "0.35.6", features = ["mm", "param"] }
[target.'cfg(windows)'.dependencies.winapi]
version = "0.3.9"

View File

@@ -47,7 +47,7 @@ impl FiberStack {
pub fn new(size: usize) -> io::Result<Self> {
// Round up our stack size request to the nearest multiple of the
// page size.
let page_size = rustix::process::page_size();
let page_size = rustix::param::page_size();
let size = if size == 0 {
page_size
} else {
@@ -57,17 +57,17 @@ impl FiberStack {
unsafe {
// Add in one page for a guard page and then ask for some memory.
let mmap_len = size + page_size;
let mmap = rustix::io::mmap_anonymous(
let mmap = rustix::mm::mmap_anonymous(
ptr::null_mut(),
mmap_len,
rustix::io::ProtFlags::empty(),
rustix::io::MapFlags::PRIVATE,
rustix::mm::ProtFlags::empty(),
rustix::mm::MapFlags::PRIVATE,
)?;
rustix::io::mprotect(
rustix::mm::mprotect(
mmap.cast::<u8>().add(page_size).cast(),
size,
rustix::io::MprotectFlags::READ | rustix::io::MprotectFlags::WRITE,
rustix::mm::MprotectFlags::READ | rustix::mm::MprotectFlags::WRITE,
)?;
Ok(Self {
@@ -90,7 +90,7 @@ impl Drop for FiberStack {
fn drop(&mut self) {
unsafe {
if let Some(len) = self.len {
let ret = rustix::io::munmap(self.top.sub(len) as _, len);
let ret = rustix::mm::munmap(self.top.sub(len) as _, len);
debug_assert!(ret.is_ok());
}
}

View File

@@ -15,7 +15,7 @@ lazy_static = {version = "1.3.0", optional = true }
object = { version = "0.28.0", default-features = false, features = ["std", "read_core"], optional = true }
[target.'cfg(target_os = "linux")'.dependencies]
rustix = { version = "0.33.7", optional = true }
rustix = { version = "0.35.6", features = ["mm", "param", "time"], optional = true }
[badges]
maintenance = { status = "actively-developed" }

View File

@@ -158,11 +158,11 @@ impl JitDumpFile {
// To match what some perf examples are doing we keep this `mmap` alive
// until this agent goes away.
let map_addr = unsafe {
let ptr = rustix::io::mmap(
let ptr = rustix::mm::mmap(
ptr::null_mut(),
rustix::process::page_size(),
rustix::io::ProtFlags::EXEC | rustix::io::ProtFlags::READ,
rustix::io::MapFlags::PRIVATE,
rustix::param::page_size(),
rustix::mm::ProtFlags::EXEC | rustix::mm::ProtFlags::READ,
rustix::mm::MapFlags::PRIVATE,
&jitdump_file,
0,
)?;
@@ -287,7 +287,7 @@ impl JitDumpFile {
impl Drop for JitDumpFile {
fn drop(&mut self) {
unsafe {
rustix::io::munmap(self.map_addr as *mut _, rustix::process::page_size()).unwrap();
rustix::mm::munmap(self.map_addr as *mut _, rustix::param::page_size()).unwrap();
}
}
}

View File

@@ -33,7 +33,7 @@ log = "0.4.8"
winapi = { version = "0.3.8", features = ["winnt", "impl-default"] }
[target.'cfg(target_os = "linux")'.dependencies]
rustix = "0.33.7"
rustix = { version = "0.35.6", features = ["process"] }
[features]
jitdump = ['wasmtime-jit-debug']

View File

@@ -31,7 +31,7 @@ memfd = { version = "0.4.1", optional = true }
mach = "0.3.2"
[target.'cfg(unix)'.dependencies]
rustix = "0.33.7"
rustix = { version = "0.35.6", features = ["mm"] }
[target.'cfg(target_os = "windows")'.dependencies]
winapi = { version = "0.3.7", features = ["winbase", "memoryapi", "errhandlingapi", "handleapi"] }

View File

@@ -333,7 +333,7 @@ impl MemoryImageSlot {
// mprotect the relevant region.
self.set_protection(
self.cur_size..size_bytes,
rustix::io::MprotectFlags::READ | rustix::io::MprotectFlags::WRITE,
rustix::mm::MprotectFlags::READ | rustix::mm::MprotectFlags::WRITE,
)?;
self.cur_size = size_bytes;
@@ -386,7 +386,7 @@ impl MemoryImageSlot {
.map_err(|e| InstantiationError::Resource(e.into()))?;
self.set_protection(
0..initial_size_bytes,
rustix::io::MprotectFlags::READ | rustix::io::MprotectFlags::WRITE,
rustix::mm::MprotectFlags::READ | rustix::mm::MprotectFlags::WRITE,
)
.map_err(|e| InstantiationError::Resource(e.into()))?;
} else if initial_size_bytes < self.initial_size {
@@ -409,7 +409,7 @@ impl MemoryImageSlot {
// mprotect(NONE) the zone from the first to the second.
self.set_protection(
initial_size_bytes..self.initial_size,
rustix::io::MprotectFlags::empty(),
rustix::mm::MprotectFlags::empty(),
)
.map_err(|e| InstantiationError::Resource(e.into()))?;
} else if initial_size_bytes > self.initial_size {
@@ -420,7 +420,7 @@ impl MemoryImageSlot {
// made visible as zeros.
self.set_protection(
self.initial_size..initial_size_bytes,
rustix::io::MprotectFlags::READ | rustix::io::MprotectFlags::WRITE,
rustix::mm::MprotectFlags::READ | rustix::mm::MprotectFlags::WRITE,
)
.map_err(|e| InstantiationError::Resource(e.into()))?;
} else {
@@ -444,11 +444,11 @@ impl MemoryImageSlot {
);
if image.len > 0 {
unsafe {
let ptr = rustix::io::mmap(
let ptr = rustix::mm::mmap(
(self.base + image.linear_memory_offset) as *mut c_void,
image.len,
rustix::io::ProtFlags::READ | rustix::io::ProtFlags::WRITE,
rustix::io::MapFlags::PRIVATE | rustix::io::MapFlags::FIXED,
rustix::mm::ProtFlags::READ | rustix::mm::ProtFlags::WRITE,
rustix::mm::MapFlags::PRIVATE | rustix::mm::MapFlags::FIXED,
image.fd.as_file(),
image.fd_offset,
)
@@ -477,10 +477,10 @@ impl MemoryImageSlot {
// semantics we want for reuse between instances, so it's all we
// need to do.
unsafe {
rustix::io::madvise(
rustix::mm::madvise(
self.base as *mut c_void,
self.cur_size,
rustix::io::Advice::LinuxDontNeed,
rustix::mm::Advice::LinuxDontNeed,
)?;
}
} else {
@@ -499,20 +499,20 @@ impl MemoryImageSlot {
// mprotect the initial heap region beyond the initial heap size back to PROT_NONE.
self.set_protection(
self.initial_size..self.cur_size,
rustix::io::MprotectFlags::empty(),
rustix::mm::MprotectFlags::empty(),
)?;
self.cur_size = self.initial_size;
self.dirty = false;
Ok(())
}
fn set_protection(&self, range: Range<usize>, flags: rustix::io::MprotectFlags) -> Result<()> {
fn set_protection(&self, range: Range<usize>, flags: rustix::mm::MprotectFlags) -> Result<()> {
assert!(range.start <= range.end);
assert!(range.end <= self.static_size);
let mprotect_start = self.base.checked_add(range.start).unwrap();
if range.len() > 0 {
unsafe {
rustix::io::mprotect(mprotect_start as *mut _, range.len(), flags)?;
rustix::mm::mprotect(mprotect_start as *mut _, range.len(), flags)?;
}
}
@@ -532,11 +532,11 @@ impl MemoryImageSlot {
/// inaccessible. Used both during instantiate and during drop.
fn reset_with_anon_memory(&self) -> Result<()> {
unsafe {
let ptr = rustix::io::mmap_anonymous(
let ptr = rustix::mm::mmap_anonymous(
self.base as *mut c_void,
self.static_size,
rustix::io::ProtFlags::empty(),
rustix::io::MapFlags::PRIVATE | rustix::io::MapFlags::FIXED,
rustix::mm::ProtFlags::empty(),
rustix::mm::MapFlags::PRIVATE | rustix::mm::MapFlags::FIXED,
)?;
assert_eq!(ptr as usize, self.base);
}

View File

@@ -12,7 +12,7 @@ fn decommit(addr: *mut u8, len: usize, protect: bool) -> Result<()> {
}
// On Linux, this is enough to cause the kernel to initialize the pages to 0 on next access
rustix::io::madvise(addr as _, len, rustix::io::Advice::LinuxDontNeed)
rustix::mm::madvise(addr as _, len, rustix::mm::Advice::LinuxDontNeed)
.context("madvise failed to decommit: {}")?;
}

View File

@@ -10,15 +10,15 @@ fn decommit(addr: *mut u8, len: usize, protect: bool) -> Result<()> {
// The new mapping will be to the CoW zero page, so this effectively
// zeroes the pages.
unsafe {
rustix::io::mmap_anonymous(
rustix::mm::mmap_anonymous(
addr as _,
len,
if protect {
rustix::io::ProtFlags::empty()
rustix::mm::ProtFlags::empty()
} else {
rustix::io::ProtFlags::READ | rustix::io::ProtFlags::WRITE
rustix::mm::ProtFlags::READ | rustix::mm::ProtFlags::WRITE
},
rustix::io::MapFlags::PRIVATE | rustix::io::MapFlags::FIXED,
rustix::mm::MapFlags::PRIVATE | rustix::mm::MapFlags::FIXED,
)
.context("mmap failed to remap pages: {}")?;
}

View File

@@ -64,11 +64,11 @@ impl Mmap {
.len();
let len = usize::try_from(len).map_err(|_| anyhow!("file too large to map"))?;
let ptr = unsafe {
rustix::io::mmap(
rustix::mm::mmap(
ptr::null_mut(),
len,
rustix::io::ProtFlags::READ,
rustix::io::MapFlags::PRIVATE,
rustix::mm::ProtFlags::READ,
rustix::mm::MapFlags::PRIVATE,
&file,
0,
)
@@ -171,11 +171,11 @@ impl Mmap {
Ok(if accessible_size == mapping_size {
// Allocate a single read-write region at once.
let ptr = unsafe {
rustix::io::mmap_anonymous(
rustix::mm::mmap_anonymous(
ptr::null_mut(),
mapping_size,
rustix::io::ProtFlags::READ | rustix::io::ProtFlags::WRITE,
rustix::io::MapFlags::PRIVATE,
rustix::mm::ProtFlags::READ | rustix::mm::ProtFlags::WRITE,
rustix::mm::MapFlags::PRIVATE,
)
.context(format!("mmap failed to allocate {:#x} bytes", mapping_size))?
};
@@ -188,11 +188,11 @@ impl Mmap {
} else {
// Reserve the mapping size.
let ptr = unsafe {
rustix::io::mmap_anonymous(
rustix::mm::mmap_anonymous(
ptr::null_mut(),
mapping_size,
rustix::io::ProtFlags::empty(),
rustix::io::MapFlags::PRIVATE,
rustix::mm::ProtFlags::empty(),
rustix::mm::MapFlags::PRIVATE,
)
.context(format!("mmap failed to allocate {:#x} bytes", mapping_size))?
};
@@ -430,7 +430,7 @@ impl Drop for Mmap {
#[cfg(not(target_os = "windows"))]
fn drop(&mut self) {
if self.len != 0 {
unsafe { rustix::io::munmap(self.ptr as *mut std::ffi::c_void, self.len) }
unsafe { rustix::mm::munmap(self.ptr as *mut std::ffi::c_void, self.len) }
.expect("munmap failed");
}
}

View File

@@ -295,21 +295,21 @@ pub fn lazy_per_thread_init() -> Result<(), Box<Trap>> {
let guard_size = page_size;
let alloc_size = guard_size + MIN_STACK_SIZE;
let ptr = rustix::io::mmap_anonymous(
let ptr = rustix::mm::mmap_anonymous(
null_mut(),
alloc_size,
rustix::io::ProtFlags::empty(),
rustix::io::MapFlags::PRIVATE,
rustix::mm::ProtFlags::empty(),
rustix::mm::MapFlags::PRIVATE,
)
.map_err(|_| Box::new(Trap::oom()))?;
// Prepare the stack with readable/writable memory and then register it
// with `sigaltstack`.
let stack_ptr = (ptr as usize + guard_size) as *mut std::ffi::c_void;
rustix::io::mprotect(
rustix::mm::mprotect(
stack_ptr,
MIN_STACK_SIZE,
rustix::io::MprotectFlags::READ | rustix::io::MprotectFlags::WRITE,
rustix::mm::MprotectFlags::READ | rustix::mm::MprotectFlags::WRITE,
)
.expect("mprotect to configure memory for sigaltstack failed");
let new_stack = libc::stack_t {
@@ -335,7 +335,7 @@ pub fn lazy_per_thread_init() -> Result<(), Box<Trap>> {
fn drop(&mut self) {
unsafe {
// Deallocate the stack memory.
let r = rustix::io::munmap(self.mmap_ptr, self.mmap_size);
let r = rustix::mm::munmap(self.mmap_ptr, self.mmap_size);
debug_assert!(r.is_ok(), "munmap failed during thread shutdown");
}
}

View File

@@ -21,7 +21,7 @@ tempfile = "3.1.0"
os_pipe = "0.9"
anyhow = "1.0.19"
wat = "1.0.42"
cap-std = "0.24.1"
cap-std = "0.25.0"
tokio = { version = "1.8.0", features = ["rt-multi-thread"] }
[features]

View File

@@ -22,16 +22,22 @@ anyhow = "1.0"
thiserror = "1.0"
wiggle = { path = "../wiggle", default-features = false, version = "=0.39.0" }
tracing = "0.1.19"
cap-std = "0.24.1"
cap-rand = "0.24.1"
cap-std = "0.25.0"
cap-rand = "0.25.0"
bitflags = "1.2"
[target.'cfg(unix)'.dependencies]
rustix = "0.33.7"
rustix = { version = "0.35.6", features = ["fs"] }
[target.'cfg(windows)'.dependencies]
io-extras = "0.13.2"
winapi = "0.3"
io-extras = "0.15.0"
[target.'cfg(windows)'.dependencies.windows-sys]
version = "0.36.0"
features = [
"Win32_Foundation",
"Win32_Networking_WinSock",
]
[badges]
maintenance = { status = "actively-developed" }

View File

@@ -15,23 +15,28 @@ include = ["src/**/*", "README.md", "LICENSE" ]
wasi-common = { path = "../", version = "=0.39.0" }
async-trait = "0.1"
anyhow = "1.0"
cap-std = "0.24.1"
cap-fs-ext = "0.24.1"
cap-time-ext = "0.24.1"
cap-rand = "0.24.1"
fs-set-times = "0.15.0"
system-interface = { version = "0.20.0", features = ["cap_std_impls"] }
cap-std = "0.25.0"
cap-fs-ext = "0.25.0"
cap-time-ext = "0.25.0"
cap-rand = "0.25.0"
fs-set-times = "0.17.0"
system-interface = { version = "0.21.0", features = ["cap_std_impls"] }
tracing = "0.1.19"
io-lifetimes = { version = "0.5.0", default-features = false }
is-terminal = "0.1.0"
io-lifetimes = { version = "0.7.0", default-features = false }
is-terminal = "0.3.0"
[target.'cfg(unix)'.dependencies]
rustix = "0.33.7"
rustix = { version = "0.35.6", features = ["fs"] }
[target.'cfg(windows)'.dependencies]
winapi = "0.3"
lazy_static = "1.4"
io-extras = "0.13.0"
io-extras = "0.15.0"
[target.'cfg(windows)'.dependencies.windows-sys]
version = "0.36.0"
features = [
"Win32_Foundation",
]
[dev-dependencies]
tempfile = "3.1.0"

View File

@@ -171,7 +171,9 @@ impl WasiDir for Dir {
// can't get a full metadata for.
#[cfg(windows)]
let entries = entries.filter(|entry: &Result<_, wasi_common::Error>| {
use winapi::shared::winerror::{ERROR_ACCESS_DENIED, ERROR_SHARING_VIOLATION};
use windows_sys::Win32::Foundation::{
ERROR_ACCESS_DENIED, ERROR_SHARING_VIOLATION,
};
if let Err(err) = entry {
if let Some(err) = err.downcast_ref::<std::io::Error>() {
if err.raw_os_error() == Some(ERROR_SHARING_VIOLATION as i32)

View File

@@ -213,12 +213,12 @@ macro_rules! wasi_stream_write_impl {
bufs: &mut [io::IoSliceMut<'a>],
) -> Result<u64, Error> {
use std::io::Read;
let n = Read::read_vectored(&mut *self.as_socketlike_view::<$std_ty>(), bufs)?;
let n = Read::read_vectored(&mut &*self.as_socketlike_view::<$std_ty>(), bufs)?;
Ok(n.try_into()?)
}
async fn write_vectored<'a>(&mut self, bufs: &[io::IoSlice<'a>]) -> Result<u64, Error> {
use std::io::Write;
let n = Write::write_vectored(&mut *self.as_socketlike_view::<$std_ty>(), bufs)?;
let n = Write::write_vectored(&mut &*self.as_socketlike_view::<$std_ty>(), bufs)?;
Ok(n.try_into()?)
}
async fn peek(&mut self, buf: &mut [u8]) -> Result<u64, Error> {

View File

@@ -46,7 +46,7 @@ pub async fn poll_oneoff<'a>(poll: &mut Poll<'a>) -> Result<(), Error> {
);
match rustix::io::poll(&mut pollfds, poll_timeout) {
Ok(ready) => break ready,
Err(rustix::io::Error::INTR) => continue,
Err(rustix::io::Errno::INTR) => continue,
Err(err) => return Err(err.into()),
}
};

View File

@@ -48,7 +48,7 @@ impl WasiFile for Stdin {
}
}
async fn read_vectored<'a>(&mut self, bufs: &mut [io::IoSliceMut<'a>]) -> Result<u64, Error> {
let n = self.0.as_filelike_view::<File>().read_vectored(bufs)?;
let n = (&*self.0.as_filelike_view::<File>()).read_vectored(bufs)?;
Ok(n.try_into().map_err(|_| Error::range())?)
}
async fn read_vectored_at<'a>(
@@ -140,7 +140,7 @@ macro_rules! wasi_file_write_impl {
})
}
async fn write_vectored<'a>(&mut self, bufs: &[io::IoSlice<'a>]) -> Result<u64, Error> {
let n = self.0.as_filelike_view::<File>().write_vectored(bufs)?;
let n = (&*self.0.as_filelike_view::<File>()).write_vectored(bufs)?;
Ok(n.try_into().map_err(|c| Error::range().context(c))?)
}
async fn write_vectored_at<'a>(

View File

@@ -112,67 +112,144 @@ impl TryFrom<std::io::Error> for types::Errno {
fn try_from(err: std::io::Error) -> Result<types::Errno, Error> {
#[cfg(unix)]
fn raw_error_code(err: &std::io::Error) -> Option<types::Errno> {
use rustix::io::Error;
match Error::from_io_error(err) {
Some(Error::AGAIN) => Some(types::Errno::Again),
Some(Error::PIPE) => Some(types::Errno::Pipe),
Some(Error::PERM) => Some(types::Errno::Perm),
Some(Error::NOENT) => Some(types::Errno::Noent),
Some(Error::NOMEM) => Some(types::Errno::Nomem),
Some(Error::TOOBIG) => Some(types::Errno::TooBig),
Some(Error::IO) => Some(types::Errno::Io),
Some(Error::BADF) => Some(types::Errno::Badf),
Some(Error::BUSY) => Some(types::Errno::Busy),
Some(Error::ACCESS) => Some(types::Errno::Acces),
Some(Error::FAULT) => Some(types::Errno::Fault),
Some(Error::NOTDIR) => Some(types::Errno::Notdir),
Some(Error::ISDIR) => Some(types::Errno::Isdir),
Some(Error::INVAL) => Some(types::Errno::Inval),
Some(Error::EXIST) => Some(types::Errno::Exist),
Some(Error::FBIG) => Some(types::Errno::Fbig),
Some(Error::NOSPC) => Some(types::Errno::Nospc),
Some(Error::SPIPE) => Some(types::Errno::Spipe),
Some(Error::MFILE) => Some(types::Errno::Mfile),
Some(Error::MLINK) => Some(types::Errno::Mlink),
Some(Error::NAMETOOLONG) => Some(types::Errno::Nametoolong),
Some(Error::NFILE) => Some(types::Errno::Nfile),
Some(Error::NOTEMPTY) => Some(types::Errno::Notempty),
Some(Error::LOOP) => Some(types::Errno::Loop),
Some(Error::OVERFLOW) => Some(types::Errno::Overflow),
Some(Error::ILSEQ) => Some(types::Errno::Ilseq),
Some(Error::NOTSUP) => Some(types::Errno::Notsup),
use rustix::io::Errno;
match Errno::from_io_error(err) {
Some(Errno::AGAIN) => Some(types::Errno::Again),
Some(Errno::PIPE) => Some(types::Errno::Pipe),
Some(Errno::PERM) => Some(types::Errno::Perm),
Some(Errno::NOENT) => Some(types::Errno::Noent),
Some(Errno::NOMEM) => Some(types::Errno::Nomem),
Some(Errno::TOOBIG) => Some(types::Errno::TooBig),
Some(Errno::IO) => Some(types::Errno::Io),
Some(Errno::BADF) => Some(types::Errno::Badf),
Some(Errno::BUSY) => Some(types::Errno::Busy),
Some(Errno::ACCESS) => Some(types::Errno::Acces),
Some(Errno::FAULT) => Some(types::Errno::Fault),
Some(Errno::NOTDIR) => Some(types::Errno::Notdir),
Some(Errno::ISDIR) => Some(types::Errno::Isdir),
Some(Errno::INVAL) => Some(types::Errno::Inval),
Some(Errno::EXIST) => Some(types::Errno::Exist),
Some(Errno::FBIG) => Some(types::Errno::Fbig),
Some(Errno::NOSPC) => Some(types::Errno::Nospc),
Some(Errno::SPIPE) => Some(types::Errno::Spipe),
Some(Errno::MFILE) => Some(types::Errno::Mfile),
Some(Errno::MLINK) => Some(types::Errno::Mlink),
Some(Errno::NAMETOOLONG) => Some(types::Errno::Nametoolong),
Some(Errno::NFILE) => Some(types::Errno::Nfile),
Some(Errno::NOTEMPTY) => Some(types::Errno::Notempty),
Some(Errno::LOOP) => Some(types::Errno::Loop),
Some(Errno::OVERFLOW) => Some(types::Errno::Overflow),
Some(Errno::ILSEQ) => Some(types::Errno::Ilseq),
Some(Errno::NOTSUP) => Some(types::Errno::Notsup),
Some(Errno::ADDRINUSE) => Some(types::Errno::Addrinuse),
Some(Errno::CANCELED) => Some(types::Errno::Canceled),
Some(Errno::ADDRNOTAVAIL) => Some(types::Errno::Addrnotavail),
Some(Errno::AFNOSUPPORT) => Some(types::Errno::Afnosupport),
Some(Errno::ALREADY) => Some(types::Errno::Already),
Some(Errno::CONNABORTED) => Some(types::Errno::Connaborted),
Some(Errno::CONNREFUSED) => Some(types::Errno::Connrefused),
Some(Errno::CONNRESET) => Some(types::Errno::Connreset),
Some(Errno::DESTADDRREQ) => Some(types::Errno::Destaddrreq),
Some(Errno::DQUOT) => Some(types::Errno::Dquot),
Some(Errno::HOSTUNREACH) => Some(types::Errno::Hostunreach),
Some(Errno::INPROGRESS) => Some(types::Errno::Inprogress),
Some(Errno::INTR) => Some(types::Errno::Intr),
Some(Errno::ISCONN) => Some(types::Errno::Isconn),
Some(Errno::MSGSIZE) => Some(types::Errno::Msgsize),
Some(Errno::NETDOWN) => Some(types::Errno::Netdown),
Some(Errno::NETRESET) => Some(types::Errno::Netreset),
Some(Errno::NETUNREACH) => Some(types::Errno::Netunreach),
Some(Errno::NOBUFS) => Some(types::Errno::Nobufs),
Some(Errno::NOPROTOOPT) => Some(types::Errno::Noprotoopt),
Some(Errno::NOTCONN) => Some(types::Errno::Notconn),
Some(Errno::NOTSOCK) => Some(types::Errno::Notsock),
Some(Errno::PROTONOSUPPORT) => Some(types::Errno::Protonosupport),
Some(Errno::PROTOTYPE) => Some(types::Errno::Prototype),
Some(Errno::STALE) => Some(types::Errno::Stale),
Some(Errno::TIMEDOUT) => Some(types::Errno::Timedout),
// On some platforms, these have the same value as other errno values.
#[allow(unreachable_patterns)]
Some(Errno::WOULDBLOCK) => Some(types::Errno::Again),
#[allow(unreachable_patterns)]
Some(Errno::OPNOTSUPP) => Some(types::Errno::Notsup),
_ => None,
}
}
#[cfg(windows)]
fn raw_error_code(err: &std::io::Error) -> Option<types::Errno> {
use winapi::shared::winerror;
use windows_sys::Win32::Foundation;
use windows_sys::Win32::Networking::WinSock;
match err.raw_os_error().map(|code| code as u32) {
Some(winerror::WSAEWOULDBLOCK) => Some(types::Errno::Again),
Some(winerror::ERROR_BAD_ENVIRONMENT) => Some(types::Errno::TooBig),
Some(winerror::ERROR_FILE_NOT_FOUND) => Some(types::Errno::Noent),
Some(winerror::ERROR_PATH_NOT_FOUND) => Some(types::Errno::Noent),
Some(winerror::ERROR_TOO_MANY_OPEN_FILES) => Some(types::Errno::Nfile),
Some(winerror::ERROR_ACCESS_DENIED) => Some(types::Errno::Acces),
Some(winerror::ERROR_SHARING_VIOLATION) => Some(types::Errno::Acces),
Some(winerror::ERROR_PRIVILEGE_NOT_HELD) => Some(types::Errno::Perm),
Some(winerror::ERROR_INVALID_HANDLE) => Some(types::Errno::Badf),
Some(winerror::ERROR_INVALID_NAME) => Some(types::Errno::Noent),
Some(winerror::ERROR_NOT_ENOUGH_MEMORY) => Some(types::Errno::Nomem),
Some(winerror::ERROR_OUTOFMEMORY) => Some(types::Errno::Nomem),
Some(winerror::ERROR_DIR_NOT_EMPTY) => Some(types::Errno::Notempty),
Some(winerror::ERROR_NOT_READY) => Some(types::Errno::Busy),
Some(winerror::ERROR_BUSY) => Some(types::Errno::Busy),
Some(winerror::ERROR_NOT_SUPPORTED) => Some(types::Errno::Notsup),
Some(winerror::ERROR_FILE_EXISTS) => Some(types::Errno::Exist),
Some(winerror::ERROR_BROKEN_PIPE) => Some(types::Errno::Pipe),
Some(winerror::ERROR_BUFFER_OVERFLOW) => Some(types::Errno::Nametoolong),
Some(winerror::ERROR_NOT_A_REPARSE_POINT) => Some(types::Errno::Inval),
Some(winerror::ERROR_NEGATIVE_SEEK) => Some(types::Errno::Inval),
Some(winerror::ERROR_DIRECTORY) => Some(types::Errno::Notdir),
Some(winerror::ERROR_ALREADY_EXISTS) => Some(types::Errno::Exist),
Some(winerror::ERROR_STOPPED_ON_SYMLINK) => Some(types::Errno::Loop),
Some(winerror::ERROR_DIRECTORY_NOT_SUPPORTED) => Some(types::Errno::Isdir),
Some(Foundation::ERROR_BAD_ENVIRONMENT) => return Some(types::Errno::TooBig),
Some(Foundation::ERROR_FILE_NOT_FOUND) => return Some(types::Errno::Noent),
Some(Foundation::ERROR_PATH_NOT_FOUND) => return Some(types::Errno::Noent),
Some(Foundation::ERROR_TOO_MANY_OPEN_FILES) => return Some(types::Errno::Nfile),
Some(Foundation::ERROR_ACCESS_DENIED) => return Some(types::Errno::Acces),
Some(Foundation::ERROR_SHARING_VIOLATION) => return Some(types::Errno::Acces),
Some(Foundation::ERROR_PRIVILEGE_NOT_HELD) => return Some(types::Errno::Perm),
Some(Foundation::ERROR_INVALID_HANDLE) => return Some(types::Errno::Badf),
Some(Foundation::ERROR_INVALID_NAME) => return Some(types::Errno::Noent),
Some(Foundation::ERROR_NOT_ENOUGH_MEMORY) => return Some(types::Errno::Nomem),
Some(Foundation::ERROR_OUTOFMEMORY) => return Some(types::Errno::Nomem),
Some(Foundation::ERROR_DIR_NOT_EMPTY) => return Some(types::Errno::Notempty),
Some(Foundation::ERROR_NOT_READY) => return Some(types::Errno::Busy),
Some(Foundation::ERROR_BUSY) => return Some(types::Errno::Busy),
Some(Foundation::ERROR_NOT_SUPPORTED) => return Some(types::Errno::Notsup),
Some(Foundation::ERROR_FILE_EXISTS) => return Some(types::Errno::Exist),
Some(Foundation::ERROR_BROKEN_PIPE) => return Some(types::Errno::Pipe),
Some(Foundation::ERROR_BUFFER_OVERFLOW) => return Some(types::Errno::Nametoolong),
Some(Foundation::ERROR_NOT_A_REPARSE_POINT) => return Some(types::Errno::Inval),
Some(Foundation::ERROR_NEGATIVE_SEEK) => return Some(types::Errno::Inval),
Some(Foundation::ERROR_DIRECTORY) => return Some(types::Errno::Notdir),
Some(Foundation::ERROR_ALREADY_EXISTS) => return Some(types::Errno::Exist),
Some(Foundation::ERROR_STOPPED_ON_SYMLINK) => return Some(types::Errno::Loop),
Some(Foundation::ERROR_DIRECTORY_NOT_SUPPORTED) => {
return Some(types::Errno::Isdir)
}
_ => {}
}
match err.raw_os_error() {
Some(WinSock::WSAEWOULDBLOCK) => Some(types::Errno::Again),
Some(WinSock::WSAECANCELLED) => Some(types::Errno::Canceled),
Some(WinSock::WSA_E_CANCELLED) => Some(types::Errno::Canceled),
Some(WinSock::WSAEBADF) => Some(types::Errno::Badf),
Some(WinSock::WSAEFAULT) => Some(types::Errno::Fault),
Some(WinSock::WSAEINVAL) => Some(types::Errno::Inval),
Some(WinSock::WSAEMFILE) => Some(types::Errno::Mfile),
Some(WinSock::WSAENAMETOOLONG) => Some(types::Errno::Nametoolong),
Some(WinSock::WSAENOTEMPTY) => Some(types::Errno::Notempty),
Some(WinSock::WSAELOOP) => Some(types::Errno::Loop),
Some(WinSock::WSAEOPNOTSUPP) => Some(types::Errno::Notsup),
Some(WinSock::WSAEADDRINUSE) => Some(types::Errno::Addrinuse),
Some(WinSock::WSAEACCES) => Some(types::Errno::Acces),
Some(WinSock::WSAEADDRNOTAVAIL) => Some(types::Errno::Addrnotavail),
Some(WinSock::WSAEAFNOSUPPORT) => Some(types::Errno::Afnosupport),
Some(WinSock::WSAEALREADY) => Some(types::Errno::Already),
Some(WinSock::WSAECONNABORTED) => Some(types::Errno::Connaborted),
Some(WinSock::WSAECONNREFUSED) => Some(types::Errno::Connrefused),
Some(WinSock::WSAECONNRESET) => Some(types::Errno::Connreset),
Some(WinSock::WSAEDESTADDRREQ) => Some(types::Errno::Destaddrreq),
Some(WinSock::WSAEDQUOT) => Some(types::Errno::Dquot),
Some(WinSock::WSAEHOSTUNREACH) => Some(types::Errno::Hostunreach),
Some(WinSock::WSAEINPROGRESS) => Some(types::Errno::Inprogress),
Some(WinSock::WSAEINTR) => Some(types::Errno::Intr),
Some(WinSock::WSAEISCONN) => Some(types::Errno::Isconn),
Some(WinSock::WSAEMSGSIZE) => Some(types::Errno::Msgsize),
Some(WinSock::WSAENETDOWN) => Some(types::Errno::Netdown),
Some(WinSock::WSAENETRESET) => Some(types::Errno::Netreset),
Some(WinSock::WSAENETUNREACH) => Some(types::Errno::Netunreach),
Some(WinSock::WSAENOBUFS) => Some(types::Errno::Nobufs),
Some(WinSock::WSAENOPROTOOPT) => Some(types::Errno::Noprotoopt),
Some(WinSock::WSAENOTCONN) => Some(types::Errno::Notconn),
Some(WinSock::WSAENOTSOCK) => Some(types::Errno::Notsock),
Some(WinSock::WSAEPROTONOSUPPORT) => Some(types::Errno::Protonosupport),
Some(WinSock::WSAEPROTOTYPE) => Some(types::Errno::Prototype),
Some(WinSock::WSAESTALE) => Some(types::Errno::Stale),
Some(WinSock::WSAETIMEDOUT) => Some(types::Errno::Timedout),
_ => None,
}
}

View File

@@ -15,20 +15,19 @@ wasi-common = { path = "../", version = "=0.39.0" }
wasi-cap-std-sync = { path = "../cap-std-sync", version = "=0.39.0" }
wiggle = { path = "../../wiggle", version = "=0.39.0" }
tokio = { version = "1.8.0", features = [ "rt", "fs", "time", "io-util", "net", "io-std", "rt-multi-thread"] }
cap-std = "0.24.1"
cap-std = "0.25.0"
anyhow = "1"
io-lifetimes = { version = "0.5.0", default-features = false }
io-lifetimes = { version = "0.7.0", default-features = false }
[target.'cfg(unix)'.dependencies]
rustix = "0.33.7"
rustix = { version = "0.35.6", features = ["fs"] }
[target.'cfg(windows)'.dependencies]
winapi = "0.3"
lazy_static = "1.4"
io-extras = "0.13.0"
io-extras = "0.15.0"
[dev-dependencies]
tempfile = "3.1.0"
tokio = { version = "1.8.0", features = [ "macros" ] }
anyhow = "1"
cap-tempfile = "0.24.1"
cap-tempfile = "0.25.0"