Skip to content

Commit

Permalink
Update most of wasi-cli.
Browse files Browse the repository at this point in the history
  • Loading branch information
sunfishcode committed Jan 24, 2024
1 parent 0ae1059 commit fcab1c7
Show file tree
Hide file tree
Showing 19 changed files with 1,266 additions and 1,039 deletions.
Binary file modified lib/virtual_adapter.debug.wasm
Binary file not shown.
Binary file modified lib/virtual_adapter.wasm
Binary file not shown.
203 changes: 111 additions & 92 deletions src/virt_deny/sockets.rs

Large diffs are not rendered by default.

282 changes: 156 additions & 126 deletions src/virt_io/sockets.rs

Large diffs are not rendered by default.

192 changes: 113 additions & 79 deletions virtual-adapter/src/io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,20 +28,24 @@ use crate::exports::wasi::io::streams::{
StreamError,
};
use crate::exports::wasi::sockets::ip_name_lookup::{
Guest as IpNameLookup, GuestResolveAddressStream, IpAddress, IpAddressFamily, Network,
ResolveAddressStream,
Guest as IpNameLookup, GuestResolveAddressStream, IpAddress, Network, ResolveAddressStream,
};
use crate::exports::wasi::sockets::tcp::{
ErrorCode as NetworkErrorCode, GuestTcpSocket, IpSocketAddress, ShutdownType, TcpSocket,
Duration, ErrorCode as NetworkErrorCode, GuestTcpSocket, IpSocketAddress, ShutdownType,
TcpSocket,
};
use crate::exports::wasi::sockets::udp::{
GuestIncomingDatagramStream, GuestOutgoingDatagramStream, GuestUdpSocket, IncomingDatagram,
OutgoingDatagram, UdpSocket,
};
use crate::exports::wasi::sockets::udp::{Datagram, GuestUdpSocket, UdpSocket};

use crate::wasi::cli::stderr;
use crate::wasi::cli::stdin;
use crate::wasi::cli::stdout;
use crate::wasi::filesystem::preopens;
use crate::wasi::filesystem::types as filesystem_types;
use crate::wasi::io::streams;
use crate::wasi::sockets::network::IpAddressFamily;

// these are all the subsystems which touch streams + poll
use crate::wasi::clocks::monotonic_clock;
Expand Down Expand Up @@ -422,6 +426,8 @@ pub struct HttpResponseOutparam(http_types::ResponseOutparam);
pub struct SocketsResolveAddressStream(ip_name_lookup::ResolveAddressStream);
pub struct SocketsTcpSocket(tcp::TcpSocket);
pub struct SocketsUdpSocket(udp::UdpSocket);
pub struct SocketsIncomingDatagramStream(udp::IncomingDatagramStream);
pub struct SocketsOutgoingDatagramStream(udp::OutgoingDatagramStream);

pub struct IoState {
initialized: bool,
Expand Down Expand Up @@ -684,12 +690,10 @@ impl IpNameLookup for VirtAdapter {
fn resolve_addresses(
network: &Network,
name: String,
address_family: Option<IpAddressFamily>,
include_unavailable: bool,
) -> Result<Resource<ResolveAddressStream>, NetworkErrorCode> {
debug!("CALL wasi:sockets/ip-name-lookup#resolve-addresses");
Ok(Resource::new(SocketsResolveAddressStream(
ip_name_lookup::resolve_addresses(network, &name, address_family, include_unavailable)?,
ip_name_lookup::resolve_addresses(network, &name)?,
)))
}
}
Expand Down Expand Up @@ -1453,45 +1457,57 @@ impl GuestTcpSocket for TcpSocket {
debug!("CALL wasi:sockets/tcp#tcp-socket.remote-address");
self.0.remote_address()
}
fn is_listening(&self) -> bool {
debug!("CALL wasi:sockets/tcp#tcp-socket.is-listening");
self.0.is_listening()
}
fn address_family(&self) -> IpAddressFamily {
debug!("CALL wasi:sockets/tcp#tcp-socket.address-family");
self.0.address_family()
}
fn ipv6_only(&self) -> Result<bool, NetworkErrorCode> {
debug!("CALL wasi:sockets/tcp#tcp-socket.ipv6-only");
self.0.ipv6_only()
}
fn set_ipv6_only(&self, value: bool) -> Result<(), NetworkErrorCode> {
debug!("CALL wasi:sockets/tcp#tcp-socket.set-ipv6-only");
self.0.set_ipv6_only(value)
}
fn set_listen_backlog_size(&self, value: u64) -> Result<(), NetworkErrorCode> {
debug!("CALL wasi:sockets/tcp#tcp-socket.set-listen-backlog-size");
self.0.set_listen_backlog_size(value)
}
fn keep_alive(&self) -> Result<bool, NetworkErrorCode> {
debug!("CALL wasi:sockets/tcp#tcp-socket.keep-alive");
self.0.keep_alive()
fn keep_alive_enabled(&self) -> Result<bool, NetworkErrorCode> {
debug!("CALL wasi:sockets/tcp#tcp-socket.keep-alive-enabled");
self.0.keep_alive_enabled()
}
fn set_keep_alive(&self, value: bool) -> Result<(), NetworkErrorCode> {
debug!("CALL wasi:sockets/tcp#tcp-socket.set-keep-alive");
self.0.set_keep_alive(value)
fn set_keep_alive_enabled(&self, value: bool) -> Result<(), NetworkErrorCode> {
debug!("CALL wasi:sockets/tcp#tcp-socket.set-keep-alive-enabled");
self.0.set_keep_alive_enabled(value)
}
fn no_delay(&self) -> Result<bool, NetworkErrorCode> {
debug!("CALL wasi:sockets/tcp#tcp-socket.no-delay");
self.0.no_delay()
fn keep_alive_idle_time(&self) -> Result<Duration, NetworkErrorCode> {
debug!("CALL wasi:sockets/tcp#tcp-socket.keep-alive-idle-time");
self.0.keep_alive_idle_time()
}
fn set_no_delay(&self, value: bool) -> Result<(), NetworkErrorCode> {
debug!("CALL wasi:sockets/tcp#tcp-socket.set-no-delay");
self.0.set_no_delay(value)
fn set_keep_alive_idle_time(&self, value: Duration) -> Result<(), NetworkErrorCode> {
debug!("CALL wasi:sockets/tcp#tcp-socket.set-keep-alive-idle-time");
self.0.set_keep_alive_idle_time(value)
}
fn unicast_hop_limit(&self) -> Result<u8, NetworkErrorCode> {
debug!("CALL wasi:sockets/tcp#tcp-socket.unicast-hop-limit");
self.0.unicast_hop_limit()
fn keep_alive_interval(&self) -> Result<Duration, NetworkErrorCode> {
debug!("CALL wasi:sockets/tcp#tcp-socket.keep-alive-interval-time");
self.0.keep_alive_interval()
}
fn set_unicast_hop_limit(&self, value: u8) -> Result<(), NetworkErrorCode> {
debug!("CALL wasi:sockets/tcp#tcp-socket.set-unicast-hop-limit");
self.0.set_unicast_hop_limit(value)
fn set_keep_alive_interval(&self, value: Duration) -> Result<(), NetworkErrorCode> {
debug!("CALL wasi:sockets/tcp#tcp-socket.set-keep-alive-interval-time");
self.0.set_keep_alive_interval(value)
}
fn keep_alive_count(&self) -> Result<u32, NetworkErrorCode> {
debug!("CALL wasi:sockets/tcp#tcp-socket.keep-alive-count-time");
self.0.keep_alive_count()
}
fn set_keep_alive_count(&self, value: u32) -> Result<(), NetworkErrorCode> {
debug!("CALL wasi:sockets/tcp#tcp-socket.set-keep-alive-count-time");
self.0.set_keep_alive_count(value)
}
fn hop_limit(&self) -> Result<u8, NetworkErrorCode> {
debug!("CALL wasi:sockets/tcp#tcp-socket.hop-limit");
self.0.hop_limit()
}
fn set_hop_limit(&self, value: u8) -> Result<(), NetworkErrorCode> {
debug!("CALL wasi:sockets/tcp#tcp-socket.set-hop-limit");
self.0.set_hop_limit(value)
}
fn receive_buffer_size(&self) -> Result<u64, NetworkErrorCode> {
debug!("CALL wasi:sockets/tcp#tcp-socket.receive-buffer-size");
Expand Down Expand Up @@ -1536,44 +1552,6 @@ impl GuestUdpSocket for UdpSocket {
debug!("CALL wasi:sockets/udp#udp-socket.finish-bind");
self.0.finish_bind()
}
fn start_connect(
&self,
network: &Network,
remote_address: IpSocketAddress,
) -> Result<(), NetworkErrorCode> {
debug!("CALL wasi:sockets/udp#udp-socket.start-connect");
self.0.start_connect(network, remote_address)
}
fn finish_connect(&self) -> Result<(), NetworkErrorCode> {
debug!("CALL wasi:sockets/udp#udp-socket.finish-connect");
self.0.finish_connect()
}
fn receive(&self, max_results: u64) -> Result<Vec<Datagram>, NetworkErrorCode> {
debug!("CALL wasi:sockets/udp#udp-socket.receive");
match self.0.receive(max_results) {
Ok(mut datagrams) => Ok(datagrams
.drain(..)
.map(|d| Datagram {
data: d.data,
remote_address: d.remote_address,
})
.collect::<Vec<Datagram>>()),
Err(err) => Err(err),
}
}
fn send(&self, mut datagrams: Vec<Datagram>) -> Result<u64, NetworkErrorCode> {
debug!("CALL wasi:sockets/udp#udp-socket.send");
self.0.send(
datagrams
.drain(..)
.map(|d| udp::Datagram {
data: d.data,
remote_address: d.remote_address,
})
.collect::<Vec<udp::Datagram>>()
.as_slice(),
)
}
fn local_address(&self) -> Result<IpSocketAddress, NetworkErrorCode> {
debug!("CALL wasi:sockets/udp#udp-socket.local-address");
self.0.local_address()
Expand All @@ -1586,14 +1564,6 @@ impl GuestUdpSocket for UdpSocket {
debug!("CALL wasi:sockets/udp#udp-socket.address-family");
self.0.address_family()
}
fn ipv6_only(&self) -> Result<bool, NetworkErrorCode> {
debug!("CALL wasi:sockets/udp#udp-socket.ipv6-only");
self.0.ipv6_only()
}
fn set_ipv6_only(&self, value: bool) -> Result<(), NetworkErrorCode> {
debug!("CALL wasi:sockets/udp#udp-socket.set-ipv6-only");
self.0.set_ipv6_only(value)
}
fn unicast_hop_limit(&self) -> Result<u8, NetworkErrorCode> {
debug!("CALL wasi:sockets/udp#udp-socket.unicast-hop-limit");
self.0.unicast_hop_limit()
Expand Down Expand Up @@ -1622,6 +1592,70 @@ impl GuestUdpSocket for UdpSocket {
debug!("CALL wasi:sockets/udp#udp-socket.subscribe");
Resource::new(Pollable::Host(self.0.subscribe()))
}
fn stream(
&self,
remote_addr: Option<IpSocketAddress>,
) -> Result<
(
Resource<SocketsIncomingDatagramStream>,
Resource<SocketsOutgoingDatagramStream>,
),
NetworkErrorCode,
> {
debug!("CALL wasi:sockets/udp#udp-socket.stream");
let (in_, out) = self.0.stream(remote_addr)?;
Ok((
Resource::new(SocketsIncomingDatagramStream(in_)),
Resource::new(SocketsOutgoingDatagramStream(out)),
))
}
}

impl GuestIncomingDatagramStream for SocketsIncomingDatagramStream {
fn receive(&self, max_results: u64) -> Result<Vec<IncomingDatagram>, NetworkErrorCode> {
debug!("CALL wasi:sockets/udp#incoming-datagram-stream.receive");
match self.0.receive(max_results) {
Ok(mut datagrams) => Ok(datagrams
.drain(..)
.map(|d| IncomingDatagram {
data: d.data,
remote_address: d.remote_address,
})
.collect::<Vec<IncomingDatagram>>()),
Err(err) => Err(err),
}
}

fn subscribe(&self) -> Resource<IoPollable> {
debug!("CALL wasi:sockets/udp#incoming-datagram-stream.subscribe");
Resource::new(Pollable::Host(self.0.subscribe()))
}
}

impl GuestOutgoingDatagramStream for SocketsOutgoingDatagramStream {
fn check_send(&self) -> Result<u64, NetworkErrorCode> {
debug!("CALL wasi:sockets/udp#outgoing-datagram-stream.check-send");
self.0.check_send()
}

fn send(&self, mut datagrams: Vec<OutgoingDatagram>) -> Result<u64, NetworkErrorCode> {
debug!("CALL wasi:sockets/udp#outgoing-datagram-stream.send");
self.0.send(
datagrams
.drain(..)
.map(|d| udp::OutgoingDatagram {
data: d.data,
remote_address: d.remote_address,
})
.collect::<Vec<udp::OutgoingDatagram>>()
.as_slice(),
)
}

fn subscribe(&self) -> Resource<IoPollable> {
debug!("CALL wasi:sockets/udp#outgoing-datagram-stream.subscribe");
Resource::new(Pollable::Host(self.0.subscribe()))
}
}

fn descriptor_ty_map(d: filesystem_types::DescriptorType) -> DescriptorType {
Expand Down
2 changes: 2 additions & 0 deletions virtual-adapter/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,5 +44,7 @@ wit_bindgen::generate!({
"wasi:sockets/ip-name-lookup/resolve-address-stream": io::SocketsResolveAddressStream,
"wasi:sockets/tcp/tcp-socket": io::SocketsTcpSocket,
"wasi:sockets/udp/udp-socket": io::SocketsUdpSocket,
"wasi:sockets/udp/incoming-datagram-stream": io::SocketsIncomingDatagramStream,
"wasi:sockets/udp/outgoing-datagram-stream": io::SocketsOutgoingDatagramStream,
}
});
2 changes: 1 addition & 1 deletion wit/deps/cli/imports.wit
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package wasi:[email protected];
world imports {
include wasi:clocks/imports@0.2.0-rc-2023-11-10;
include wasi:filesystem/imports@0.2.0-rc-2023-11-10;
include wasi:sockets/imports@0.2.0-rc-2023-10-18;
include wasi:sockets/imports@0.2.0-rc-2024-01-16;
include wasi:random/imports@0.2.0-rc-2023-11-10;
include wasi:io/imports@0.2.0-rc-2023-11-10;

Expand Down
18 changes: 10 additions & 8 deletions wit/deps/cli/terminal.wit
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
/// Terminal input.
///
/// In the future, this may include functions for disabling echoing,
/// disabling input buffering so that keyboard events are sent through
/// immediately, querying supported features, and so on.
interface terminal-input {
/// The input side of a terminal.
resource terminal-input;

// In the future, this may include functions for disabling echoing,
// disabling input buffering so that keyboard events are sent through
// immediately, querying supported features, and so on.
}

/// Terminal output.
///
/// In the future, this may include functions for querying the terminal
/// size, being notified of terminal size changes, querying supported
/// features, and so on.
interface terminal-output {
/// The output side of a terminal.
resource terminal-output;

// In the future, this may include functions for querying the terminal
// size, being notified of terminal size changes, querying supported
// features, and so on.
}

/// An interface providing an optional `terminal-input` for stdin as a
Expand Down
2 changes: 1 addition & 1 deletion wit/deps/io/poll.wit
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package wasi:[email protected];
/// A poll API intended to let users wait for I/O events on multiple handles
/// at once.
interface poll {
/// `pollable` epresents a single I/O event which may be ready, or not.
/// `pollable` represents a single I/O event which may be ready, or not.
resource pollable {

/// Return the readiness of a pollable. This function never blocks.
Expand Down
21 changes: 16 additions & 5 deletions wit/deps/io/streams.wit
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ interface streams {
resource input-stream {
/// Perform a non-blocking read from the stream.
///
/// When the source of a `read` is binary data, the bytes from the source
/// are returned verbatim. When the source of a `read` is known to the
/// implementation to be text, bytes containing the UTF-8 encoding of the
/// text are returned.
///
/// This function returns a list of bytes containing the read data,
/// when successful. The returned list will contain up to `len` bytes;
/// it may return fewer than requested, but not more. The list is
Expand Down Expand Up @@ -111,6 +116,12 @@ interface streams {

/// Perform a write. This function never blocks.
///
/// When the destination of a `write` is binary data, the bytes from
/// `contents` are written verbatim. When the destination of a `write` is
/// known to the implementation to be text, the bytes of `contents` are
/// transcoded from UTF-8 into the encoding of the destination and then
/// written.
///
/// Precondition: check-write gave permit of Ok(n) and contents has a
/// length of less than or equal to n. Otherwise, this function will trap.
///
Expand All @@ -131,7 +142,7 @@ interface streams {
/// let pollable = this.subscribe();
/// while !contents.is_empty() {
/// // Wait for the stream to become writable
/// poll-one(pollable);
/// pollable.block();
/// let Ok(n) = this.check-write(); // eliding error handling
/// let len = min(n, contents.len());
/// let (chunk, rest) = contents.split_at(len);
Expand All @@ -140,7 +151,7 @@ interface streams {
/// }
/// this.flush();
/// // Wait for completion of `flush`
/// poll-one(pollable);
/// pollable.block();
/// // Check for any errors that arose during `flush`
/// let _ = this.check-write(); // eliding error handling
/// ```
Expand Down Expand Up @@ -178,7 +189,7 @@ interface streams {

/// Write zeroes to a stream.
///
/// this should be used precisely like `write` with the exact same
/// This should be used precisely like `write` with the exact same
/// preconditions (must use check-write first), but instead of
/// passing a list of bytes, you simply pass the number of zero-bytes
/// that should be written.
Expand All @@ -199,15 +210,15 @@ interface streams {
/// let pollable = this.subscribe();
/// while num_zeroes != 0 {
/// // Wait for the stream to become writable
/// poll-one(pollable);
/// pollable.block();
/// let Ok(n) = this.check-write(); // eliding error handling
/// let len = min(n, num_zeroes);
/// this.write-zeroes(len); // eliding error handling
/// num_zeroes -= len;
/// }
/// this.flush();
/// // Wait for completion of `flush`
/// poll-one(pollable);
/// pollable.block();
/// // Check for any errors that arose during `flush`
/// let _ = this.check-write(); // eliding error handling
/// ```
Expand Down
Loading

0 comments on commit fcab1c7

Please sign in to comment.