Implement the remaining socket-related WASI functions. (#4776)
* Implement the remaining socket-related WASI functions. The original WASI specification included `sock_read`, `sock_write`, and `shutdown`. Now that we have some sockets support, implement these additional functions, to make it easier for people porting existing code to WASI. It's expected that this will all be subsumed by the wasi-sockets proposal, but for now, this is a relatively small change which should hopefully unblock people trying to use the current `accept` support. * Update to system-interface 0.22, which has fixes for Windows.
This commit is contained in:
4
Cargo.lock
generated
4
Cargo.lock
generated
@@ -2782,9 +2782,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "system-interface"
|
||||
version = "0.21.0"
|
||||
version = "0.22.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2e3e98c4cf2f43a7e3b3a943b63fd192559b8a98ddcbef260580f29f0f4b9d1b"
|
||||
checksum = "fa85f9e64bd72b222ced152d2694fd306c0ebe43670cb9d187701874b7b89008"
|
||||
dependencies = [
|
||||
"atty",
|
||||
"bitflags",
|
||||
|
||||
@@ -32,14 +32,7 @@ Please note that the library requires Rust compiler version at least 1.37.0.
|
||||
|
||||
### *nix
|
||||
In our *nix implementation, we currently support the entire [WASI API]
|
||||
with the exception of socket hostcalls:
|
||||
- `sock_recv`
|
||||
- `sock_send`
|
||||
- `sock_shutdown`
|
||||
|
||||
We expect these to be implemented when network access is standardised.
|
||||
|
||||
We also currently do not support the `proc_raise` hostcall, as it is expected to
|
||||
with the exception of the `proc_raise` hostcall, as it is expected to
|
||||
be dropped entirely from WASI.
|
||||
|
||||
[WASI API]: https://github.com/WebAssembly/WASI/blob/master/phases/snapshot/docs.md
|
||||
|
||||
@@ -20,7 +20,7 @@ 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"] }
|
||||
system-interface = { version = "0.22.0", features = ["cap_std_impls"] }
|
||||
tracing = "0.1.19"
|
||||
io-lifetimes = { version = "0.7.0", default-features = false }
|
||||
is-terminal = "0.3.0"
|
||||
|
||||
@@ -7,7 +7,7 @@ use std::convert::TryInto;
|
||||
use std::io;
|
||||
use system_interface::{
|
||||
fs::{FileIoExt, GetSetFdFlags},
|
||||
io::ReadReady,
|
||||
io::{IoExt, ReadReady},
|
||||
};
|
||||
use wasi_common::{
|
||||
file::{Advice, FdFlags, FileType, Filestat, WasiFile},
|
||||
|
||||
@@ -9,13 +9,12 @@ use std::any::Any;
|
||||
use std::convert::TryInto;
|
||||
use std::io;
|
||||
#[cfg(unix)]
|
||||
use system_interface::fs::FileIoExt;
|
||||
#[cfg(unix)]
|
||||
use system_interface::fs::GetSetFdFlags;
|
||||
use system_interface::io::IoExt;
|
||||
use system_interface::io::IsReadWrite;
|
||||
use system_interface::io::ReadReady;
|
||||
use wasi_common::{
|
||||
file::{FdFlags, FileType, WasiFile},
|
||||
file::{FdFlags, FileType, RiFlags, RoFlags, SdFlags, SiFlags, WasiFile},
|
||||
Error, ErrorExt,
|
||||
};
|
||||
|
||||
@@ -243,6 +242,61 @@ macro_rules! wasi_stream_write_impl {
|
||||
Err(Error::io())
|
||||
}
|
||||
}
|
||||
|
||||
async fn sock_recv<'a>(
|
||||
&mut self,
|
||||
ri_data: &mut [std::io::IoSliceMut<'a>],
|
||||
ri_flags: RiFlags,
|
||||
) -> Result<(u64, RoFlags), Error> {
|
||||
if (ri_flags & !(RiFlags::RECV_PEEK | RiFlags::RECV_WAITALL)) != RiFlags::empty() {
|
||||
return Err(Error::not_supported());
|
||||
}
|
||||
|
||||
if ri_flags.contains(RiFlags::RECV_PEEK) {
|
||||
if let Some(first) = ri_data.iter_mut().next() {
|
||||
let n = self.0.peek(first)?;
|
||||
return Ok((n as u64, RoFlags::empty()));
|
||||
} else {
|
||||
return Ok((0, RoFlags::empty()));
|
||||
}
|
||||
}
|
||||
|
||||
if ri_flags.contains(RiFlags::RECV_WAITALL) {
|
||||
let n: usize = ri_data.iter().map(|buf| buf.len()).sum();
|
||||
self.0.read_exact_vectored(ri_data)?;
|
||||
return Ok((n as u64, RoFlags::empty()));
|
||||
}
|
||||
|
||||
let n = self.0.read_vectored(ri_data)?;
|
||||
Ok((n as u64, RoFlags::empty()))
|
||||
}
|
||||
|
||||
async fn sock_send<'a>(
|
||||
&mut self,
|
||||
si_data: &[std::io::IoSlice<'a>],
|
||||
si_flags: SiFlags,
|
||||
) -> Result<u64, Error> {
|
||||
if si_flags != SiFlags::empty() {
|
||||
return Err(Error::not_supported());
|
||||
}
|
||||
|
||||
let n = self.0.write_vectored(si_data)?;
|
||||
Ok(n as u64)
|
||||
}
|
||||
|
||||
async fn sock_shutdown(&mut self, how: SdFlags) -> Result<(), Error> {
|
||||
let how = if how == SdFlags::RD | SdFlags::WR {
|
||||
cap_std::net::Shutdown::Both
|
||||
} else if how == SdFlags::RD {
|
||||
cap_std::net::Shutdown::Read
|
||||
} else if how == SdFlags::WR {
|
||||
cap_std::net::Shutdown::Write
|
||||
} else {
|
||||
return Err(Error::invalid_argument());
|
||||
};
|
||||
self.0.shutdown(how)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
#[cfg(unix)]
|
||||
impl AsFd for $ty {
|
||||
|
||||
@@ -194,3 +194,8 @@ criteria = "safe-to-deploy"
|
||||
version = "1.0.48"
|
||||
notes = "The Bytecode Alliance is the author of this crate."
|
||||
|
||||
[[audits.system-interface]]
|
||||
who = "Dan Gohman <dev@sunfishcode.online>"
|
||||
criteria = "safe-to-deploy"
|
||||
version = "0.22.0"
|
||||
notes = "The Bytecode Alliance is the author of this crate."
|
||||
|
||||
@@ -1011,10 +1011,6 @@ criteria = "safe-to-deploy"
|
||||
version = "0.12.6"
|
||||
criteria = "safe-to-deploy"
|
||||
|
||||
[[exemptions.system-interface]]
|
||||
version = "0.21.0"
|
||||
criteria = "safe-to-deploy"
|
||||
|
||||
[[exemptions.target-lexicon]]
|
||||
version = "0.12.3"
|
||||
criteria = "safe-to-deploy"
|
||||
|
||||
Reference in New Issue
Block a user