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:
Dan Gohman
2022-08-26 11:39:51 -07:00
committed by GitHub
parent a68fa86aad
commit 9b3477f602
7 changed files with 67 additions and 19 deletions

4
Cargo.lock generated
View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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