Bind the socket to a specific network on the provided IP address and port.
If the IP address is zero (0.0.0.0 in IPv4, :: in IPv6), it is left to the implementation to decide which
network interface(s) to bind to.
-If the TCP/UDP port is zero, the socket will be bound to a random free port.
-
When a socket is not explicitly bound, the first invocation to connect will implicitly bind the socket.
+If the port is zero, the socket will be bound to a random free port.
Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts.
Typical start errors
-
address-family-mismatch: The local-address has the wrong address family. (EINVAL)
-
already-bound: The socket is already bound. (EINVAL)
-
concurrency-conflict: Another bind or connect operation is already in progress. (EALREADY)
+
invalid-argument: The local-address has the wrong address family. (EAFNOSUPPORT, EFAULT on Windows)
+
invalid-state: The socket is already bound. (EINVAL)
Typical finish errors
-
ephemeral-ports-exhausted: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows)
+
address-in-use: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows)
address-in-use: Address is already in use. (EADDRINUSE)
address-not-bindable: local-address is not an address that the network can bind to. (EADDRNOTAVAIL)
not-in-progress: A bind operation is not in progress.
@@ -364,29 +354,38 @@ If the TCP/UDP port is zero, the socket will be bound to a random free port.
Set up inbound & outbound communication channels, optionally to a specific peer.
+
This function only changes the local socket configuration and does not generate any network traffic.
+On success, the remote-address of the socket is updated. The local-address may be updated as well,
+based on the best network path to remote-address.
+
When a remote-address is provided, the returned streams are limited to communicating with that specific peer:
+
+
send can only be used to send to this destination.
+
receive will only return datagrams sent from the provided remote-address.
+
+
This method may be called multiple times on the same socket to change its association, but
+only the most recently returned pair of streams will be operational. Implementations may trap if
+the streams returned by a previous invocation haven't been dropped yet before calling stream again.
+
The POSIX equivalent in pseudo-code is:
+
if (was previously connected) {
+ connect(s, AF_UNSPEC)
+}
+if (remote_address is Some) {
+ connect(s, remote_address)
+}
+
+
Unlike in POSIX, the socket must already be explicitly bound.
+
Typical errors
-
address-family-mismatch: The remote-address has the wrong address family. (EAFNOSUPPORT)
-
invalid-remote-address: The IP address in remote-address is set to INADDR_ANY (0.0.0.0 / ::). (EDESTADDRREQ, EADDRNOTAVAIL)
-
invalid-remote-address: The port in remote-address is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL)
-
already-attached: The socket is already bound to a different network. The network passed to connect must be identical to the one passed to bind.
-
concurrency-conflict: Another bind or connect operation is already in progress. (EALREADY)
-
-
Typical finish errors
-
-
ephemeral-ports-exhausted: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD)
-
not-in-progress: A connect operation is not in progress.
-
would-block: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN)
+
invalid-argument: The remote-address has the wrong address family. (EAFNOSUPPORT)
+
invalid-argument: remote-address is a non-IPv4-mapped IPv6 address, but the socket was bound to a specific IPv4-mapped IPv6 address. (or vice versa)
+
invalid-argument: The IP address in remote-address is set to INADDR_ANY (0.0.0.0 / ::). (EDESTADDRREQ, EADDRNOTAVAIL)
+
invalid-argument: The port in remote-address is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL)
+
invalid-state: The socket is not bound.
+
address-in-use: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD)
+
remote-unreachable: The remote address is not reachable. (ECONNRESET, ENETRESET, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET)
+
connection-refused: The connection was refused. (ECONNREFUSED)
References
@@ -397,100 +396,24 @@ If the TCP/UDP port is zero, the socket will be bound to a random free port.
This function attempts to receive up to max-results datagrams on the socket without blocking.
-The returned list may contain fewer elements than requested, but never more.
-If max-results is 0, this function returns successfully with an empty list.
-
Typical errors
-
-
not-bound: The socket is not bound to any local address. (EINVAL)
-
remote-unreachable: The remote address is not reachable. (ECONNREFUSED, ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN)
-
would-block: There is no pending data available to be read at the moment. (EWOULDBLOCK, EAGAIN)
This function attempts to send all provided datagrams on the socket without blocking and
-returns how many messages were actually sent (or queued for sending).
-
This function semantically behaves the same as iterating the datagrams list and sequentially
-sending each individual datagram until either the end of the list has been reached or the first error occurred.
-If at least one datagram has been sent successfully, this function never returns an error.
-
If the input list is empty, the function returns ok(0).
-
The remote address option is required. To send a message to the "connected" peer,
-call remote-address to get their address.
-
Typical errors
-
-
address-family-mismatch: The remote-address has the wrong address family. (EAFNOSUPPORT)
-
invalid-remote-address: The IP address in remote-address is set to INADDR_ANY (0.0.0.0 / ::). (EDESTADDRREQ, EADDRNOTAVAIL)
-
invalid-remote-address: The port in remote-address is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL)
-
already-connected: The socket is in "connected" mode and the datagram.remote-address does not match the address passed to connect. (EISCONN)
-
not-bound: The socket is not bound to any local address. Unlike POSIX, this function does not perform an implicit bind.
-
remote-unreachable: The remote address is not reachable. (ECONNREFUSED, ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN)
-
datagram-too-large: The datagram is too large. (EMSGSIZE)
-
would-block: The send buffer is currently full. (EWOULDBLOCK, EAGAIN)
The kernel buffer space reserved for sends/receives on this socket.
-
Note #1: an implementation may choose to cap or round the buffer size when setting the value.
-In other words, after setting a value, reading the same setting back may return a different value.
-
Note #2: there is not necessarily a direct relationship between the kernel buffer size and the bytes of
-actual data to be sent/received by the application, because the kernel might also use the buffer space
-for internal metadata structures.
+
If the provided value is 0, an invalid-argument error is returned.
+Any other value will never cause an error, but it might be silently clamped and/or rounded.
+I.e. after setting a value, reading the same setting back may return a different value.
Equivalent to the SO_RCVBUF and SO_SNDBUF socket options.
Typical errors
-
concurrency-conflict: (set) Another bind or connect operation is already in progress. (EALREADY)
+
invalid-argument: (set) The provided value was 0.
Params
@@ -652,7 +573,126 @@ It's planned to be removed when future is natively supported in Pre
This function attempts to receive up to max-results datagrams on the socket without blocking.
+The returned list may contain fewer elements than requested, but never more.
+
This function returns successfully with an empty list when either:
+
+
max-results is 0, or:
+
max-results is greater than 0, but no results are immediately available.
+This function never returns error(would-block).
+
+
Typical errors
+
+
remote-unreachable: The remote address is not reachable. (ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET)
+
connection-refused: The connection was refused. (ECONNREFUSED)
Check readiness for sending. This function never blocks.
+
Returns the number of datagrams permitted for the next call to send,
+or an error. Calling send with more datagrams than this function has
+permitted will trap.
+
When this function returns ok(0), the subscribe pollable will
+become ready when this function will report at least ok(1), or an
+error.
This function attempts to send all provided datagrams on the socket without blocking and
+returns how many messages were actually sent (or queued for sending). This function never
+returns error(would-block). If none of the datagrams were able to be sent, ok(0) is returned.
+
This function semantically behaves the same as iterating the datagrams list and sequentially
+sending each individual datagram until either the end of the list has been reached or the first error occurred.
+If at least one datagram has been sent successfully, this function never returns an error.
+
If the input list is empty, the function returns ok(0).
+
Each call to send must be permitted by a preceding check-send. Implementations must trap if
+either check-send was not called or datagrams contains more items than check-send permitted.
+
Typical errors
+
+
invalid-argument: The remote-address has the wrong address family. (EAFNOSUPPORT)
+
invalid-argument: remote-address is a non-IPv4-mapped IPv6 address, but the socket was bound to a specific IPv4-mapped IPv6 address. (or vice versa)
+
invalid-argument: The IP address in remote-address is set to INADDR_ANY (0.0.0.0 / ::). (EDESTADDRREQ, EADDRNOTAVAIL)
+
invalid-argument: The port in remote-address is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL)
+
invalid-argument: The socket is in "connected" mode and remote-address is some value that does not match the address passed to stream. (EISCONN)
+
invalid-argument: The socket is not "connected" and no value for remote-address was provided. (EDESTADDRREQ)
+
remote-unreachable: The remote address is not reachable. (ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET)
+
connection-refused: The connection was refused. (ECONNREFUSED)
+
datagram-too-large: The datagram is too large. (EMSGSIZE)
@@ -673,14 +713,13 @@ It's planned to be removed when future is natively supported in Pre
Create a new UDP socket.
Similar to socket(AF_INET or AF_INET6, SOCK_DGRAM, IPPROTO_UDP) in POSIX.
This function does not require a network capability handle. This is considered to be safe because
-at time of creation, the socket is not bound to any network yet. Up to the moment bind/connect is called,
+at time of creation, the socket is not bound to any network yet. Up to the moment bind is called,
the socket is effectively an in-memory configuration object, unable to communicate with the outside world.
All sockets are non-blocking. Use the wasi-poll interface to block on asynchronous operations.
Typical errors
-
not-supported: The host does not support UDP sockets. (EOPNOTSUPP)
-
address-family-not-supported: The specified address-family is not supported. (EAFNOSUPPORT)
-
new-socket-limit: The new socket resource could not be created because of a system limit. (EMFILE, ENFILE)
+
not-supported: The specified address-family is not supported. (EAFNOSUPPORT)
+
new-socket-limit: The new socket resource could not be created because of a system limit. (EMFILE, ENFILE)
References:
@@ -697,18 +736,41 @@ the socket is effectively an in-memory configuration object, unable to communica
Returns a string that is suitable to assist humans in debugging
+this error.
+
WARNING: The returned string should not be consumed mechanically!
+It may change across platforms, hosts, or other implementation
+details. Parsing this string is a major platform-compatibility
+hazard.
An instant in time, in nanoseconds. An instant is relative to an
+unspecified initial value, and can only be compared to instances from
+the same monotonic-clock.
+
@@ -1065,13 +1177,14 @@ implicitly bind the socket.
Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts.
Typical start errors
-
address-family-mismatch: The local-address has the wrong address family. (EINVAL)
-
already-bound: The socket is already bound. (EINVAL)
-
concurrency-conflict: Another bind, connect or listen operation is already in progress. (EALREADY)
+
invalid-argument: The local-address has the wrong address family. (EAFNOSUPPORT, EFAULT on Windows)
+
invalid-argument: local-address is not a unicast address. (EINVAL)
+
invalid-argument: local-address is an IPv4-mapped IPv6 address, but the socket has ipv6-only enabled. (EINVAL)
+
invalid-state: The socket is already bound. (EINVAL)
Typical finish errors
-
ephemeral-ports-exhausted: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows)
+
address-in-use: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows)
address-in-use: Address is already in use. (EADDRINUSE)
address-not-bindable: local-address is not an address that the network can bind to. (EADDRNOTAVAIL)
not-in-progress: A bind operation is not in progress.
@@ -1110,23 +1223,37 @@ implicitly bind the socket.
the socket is transitioned into the Connection state
a pair of streams is returned that can be used to read & write to the connection
+
POSIX mentions:
+
+
If connect() fails, the state of the socket is unspecified. Conforming applications should
+close the file descriptor and create a new socket before attempting to reconnect.
+
+
WASI prescribes the following behavior:
+
+
If connect fails because an input/state validation error, the socket should remain usable.
+
If a connection was actually attempted but failed, the socket should become unusable for further network communication.
+Besides drop, any method after such a failure may return an error.
+
Typical start errors
-
address-family-mismatch: The remote-address has the wrong address family. (EAFNOSUPPORT)
-
invalid-remote-address: The IP address in remote-address is set to INADDR_ANY (0.0.0.0 / ::). (EADDRNOTAVAIL on Windows)
-
invalid-remote-address: The port in remote-address is set to 0. (EADDRNOTAVAIL on Windows)
-
already-attached: The socket is already attached to a different network. The network passed to connect must be identical to the one passed to bind.
-
already-connected: The socket is already in the Connection state. (EISCONN)
-
already-listening: The socket is already in the Listener state. (EOPNOTSUPP, EINVAL on Windows)
-
concurrency-conflict: Another bind, connect or listen operation is already in progress. (EALREADY)
+
invalid-argument: The remote-address has the wrong address family. (EAFNOSUPPORT)
+
invalid-argument: remote-address is not a unicast address. (EINVAL, ENETUNREACH on Linux, EAFNOSUPPORT on MacOS)
+
invalid-argument: remote-address is an IPv4-mapped IPv6 address, but the socket has ipv6-only enabled. (EINVAL, EADDRNOTAVAIL on Illumos)
+
invalid-argument: remote-address is a non-IPv4-mapped IPv6 address, but the socket was bound to a specific IPv4-mapped IPv6 address. (or vice versa)
+
invalid-argument: The IP address in remote-address is set to INADDR_ANY (0.0.0.0 / ::). (EADDRNOTAVAIL on Windows)
+
invalid-argument: The port in remote-address is set to 0. (EADDRNOTAVAIL on Windows)
+
invalid-argument: The socket is already attached to a different network. The network passed to connect must be identical to the one passed to bind.
+
invalid-state: The socket is already in the Connection state. (EISCONN)
+
invalid-state: The socket is already in the Listener state. (EOPNOTSUPP, EINVAL on Windows)
Typical finish errors
timeout: Connection timed out. (ETIMEDOUT)
connection-refused: The connection was forcefully rejected. (ECONNREFUSED)
connection-reset: The connection was reset. (ECONNRESET)
-
remote-unreachable: The remote address is not reachable. (EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN)
-
ephemeral-ports-exhausted: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD)
+
connection-aborted: The connection was aborted. (ECONNABORTED)
+
remote-unreachable: The remote address is not reachable. (EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET)
+
address-in-use: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD)
not-in-progress: A connect operation is not in progress.
would-block: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN)
@@ -1166,14 +1293,13 @@ implicitly bind the socket.
Typical start errors
-
not-bound: The socket is not bound to any local address. (EDESTADDRREQ)
-
already-connected: The socket is already in the Connection state. (EISCONN, EINVAL on BSD)
-
already-listening: The socket is already in the Listener state.
-
concurrency-conflict: Another bind, connect or listen operation is already in progress. (EINVAL on BSD)
+
invalid-state: The socket is not bound to any local address. (EDESTADDRREQ)
+
invalid-state: The socket is already in the Connection state. (EISCONN, EINVAL on BSD)
+
invalid-state: The socket is already in the Listener state.
Typical finish errors
-
ephemeral-ports-exhausted: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE)
+
address-in-use: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE)
not-in-progress: A listen operation is not in progress.
would-block: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN)
@@ -1203,15 +1329,27 @@ implicitly bind the socket.
Hints the desired listen queue size. Implementations are free to ignore this.
+
If the provided value is 0, an invalid-argument error is returned.
+Any other value will never cause an error, but it might be silently clamped and/or rounded.
Typical errors
-
already-connected: (set) The socket is already in the Connection state.
-
concurrency-conflict: (set) A bind, connect or listen operation is already in progress. (EALREADY)
+
not-supported: (set) The platform does not support changing the backlog size after the initial listen.
+
invalid-argument: (set) The provided value was 0.
+
invalid-state: (set) The socket is already in the Connection state.
Params
@@ -1324,93 +1481,156 @@ a pair of streams that can be used to read & write to the connection.
Amount of time the connection has to be idle before TCP starts sending keepalive packets.
+
If the provided value is 0, an invalid-argument error is returned.
+Any other value will never cause an error, but it might be silently clamped and/or rounded.
+I.e. after setting a value, reading the same setting back may return a different value.
+
Equivalent to the TCP_KEEPIDLE socket option. (TCP_KEEPALIVE on MacOS)
Typical errors
-
concurrency-conflict: (set) A bind, connect or listen operation is already in progress. (EALREADY)
If the provided value is 0, an invalid-argument error is returned.
+Any other value will never cause an error, but it might be silently clamped and/or rounded.
+I.e. after setting a value, reading the same setting back may return a different value.
+
Equivalent to the TCP_KEEPINTVL socket option.
Typical errors
-
concurrency-conflict: (set) A bind, connect or listen operation is already in progress. (EALREADY)
The maximum amount of keepalive packets TCP should send before aborting the connection.
+
If the provided value is 0, an invalid-argument error is returned.
+Any other value will never cause an error, but it might be silently clamped and/or rounded.
+I.e. after setting a value, reading the same setting back may return a different value.
The kernel buffer space reserved for sends/receives on this socket.
-
Note #1: an implementation may choose to cap or round the buffer size when setting the value.
-In other words, after setting a value, reading the same setting back may return a different value.
-
Note #2: there is not necessarily a direct relationship between the kernel buffer size and the bytes of
-actual data to be sent/received by the application, because the kernel might also use the buffer space
-for internal metadata structures.
+
If the provided value is 0, an invalid-argument error is returned.
+Any other value will never cause an error, but it might be silently clamped and/or rounded.
+I.e. after setting a value, reading the same setting back may return a different value.
Equivalent to the SO_RCVBUF and SO_SNDBUF socket options.
Typical errors
-
already-connected: (set) The socket is already in the Connection state.
-
already-listening: (set) The socket is already in the Listener state.
-
concurrency-conflict: (set) A bind, connect or listen operation is already in progress. (EALREADY)
+
invalid-argument: (set) The provided value was 0.
+
invalid-state: (set) The socket is already in the Connection state.
+
invalid-state: (set) The socket is already in the Listener state.
Params
@@ -1474,7 +1694,7 @@ operations on the output-stream associ
The shutdown function does not close (drop) the socket.
Typical errors
-
not-connected: The socket is not in the Connection state. (ENOTCONN)
+
invalid-state: The socket is not in the Connection state. (ENOTCONN)
References
@@ -1492,7 +1712,7 @@ operations on the output-stream associ
@@ -1552,35 +1771,21 @@ is called, the socket is effectively an in-memory configuration object, unable t
#### `type ip-address`
[`ip-address`](#ip_address)
Resolve an internet host name to a list of IP addresses.
+
Unicode domain names are automatically converted to ASCII using IDNA encoding.
+If the input is an IP address string, the address is parsed and returned
+as-is without making any external requests.
See the wasi-socket proposal README.md for a comparison with getaddrinfo.
-
Parameters
-
-
name: The name to look up. IP addresses are not allowed. Unicode domain names are automatically converted
-to ASCII using IDNA encoding.
-
address-family: If provided, limit the results to addresses of this specific address family.
-
include-unavailable: When set to true, this function will also return addresses of which the runtime
-thinks (or knows) can't be connected to at the moment. For example, this will return IPv6 addresses on
-systems without an active IPv6 interface. Notes:
-
Even when no public IPv6 interfaces are present or active, names like "localhost" can still resolve to an IPv6 address.
-
Whatever is "available" or "unavailable" is volatile and can change everytime a network cable is unplugged.
-
-
This function never blocks. It either immediately fails or immediately returns successfully with a resolve-address-stream
-that can be used to (asynchronously) fetch the results.
-
At the moment, the stream never completes successfully with 0 items. Ie. the first call
-to resolve-next-address never returns ok(none). This may change in the future.
+
This function never blocks. It either immediately fails or immediately
+returns successfully with a resolve-address-stream that can be used
+to (asynchronously) fetch the results.
Typical errors
-
invalid-name: name is a syntactically invalid domain name.
-
invalid-name: name is an IP address.
-
address-family-not-supported: The specified address-family is not supported. (EAI_FAMILY)
+
invalid-argument: name is a syntactically invalid domain name or IP address.
References:
@@ -1593,8 +1798,6 @@ to resolve-next-address never returns ok(none). This m
diff --git a/wit/deps.lock b/wit/deps.lock
index 472b87f..be53c76 100644
--- a/wit/deps.lock
+++ b/wit/deps.lock
@@ -1,4 +1,9 @@
+[clocks]
+url = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz"
+sha256 = "89da8eca4cd195516574c89c5b3c24a7b5af3ff2565c16753d20d3bdbc5fc60f"
+sha512 = "244079b3f592d58478a97adbd0bee8d49ae9dd1a3e435651ee40997b50da9fe62cfaba7e3ec7f7406d7d0288d278a43a3a0bc5150226ba40ce0f8ac6d33f7ddb"
+
[io]
url = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz"
-sha256 = "fb76f4449eea54d06b56fc6a7ca988da51bd84a54d2021cf18da67b5e2c7ebcf"
-sha512 = "c005e2a91522958a9537827a49ae344e1cb39d66e85492901a86bcc7e322ba8d0a7f1a02c9b9f840c123b4ad97e297355fac98d4822536d1426d1096dd1d73ac"
+sha256 = "f2e6127b235c37c06be675a904d6acf08db953ea688d78c42892c6ad3bd194e4"
+sha512 = "32feefbc115c34bf6968cb6e9dc15e755698ee90648e5a5d84448917c36a318bd61b401195eb64330e2475e1d098bfb8dee1440d594a68e0797748762bd84ae5"
diff --git a/wit/deps.toml b/wit/deps.toml
index b178cb2..c07efaf 100644
--- a/wit/deps.toml
+++ b/wit/deps.toml
@@ -1 +1,2 @@
+clocks = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz"
io = "https://github.com/WebAssembly/wasi-io/archive/main.tar.gz"
diff --git a/wit/deps/clocks/monotonic-clock.wit b/wit/deps/clocks/monotonic-clock.wit
new file mode 100644
index 0000000..09ef32c
--- /dev/null
+++ b/wit/deps/clocks/monotonic-clock.wit
@@ -0,0 +1,45 @@
+package wasi:clocks@0.2.0-rc-2023-11-10;
+/// WASI Monotonic Clock is a clock API intended to let users measure elapsed
+/// time.
+///
+/// It is intended to be portable at least between Unix-family platforms and
+/// Windows.
+///
+/// A monotonic clock is a clock which has an unspecified initial value, and
+/// successive reads of the clock will produce non-decreasing values.
+///
+/// It is intended for measuring elapsed time.
+interface monotonic-clock {
+ use wasi:io/poll@0.2.0-rc-2023-11-10.{pollable};
+
+ /// An instant in time, in nanoseconds. An instant is relative to an
+ /// unspecified initial value, and can only be compared to instances from
+ /// the same monotonic-clock.
+ type instant = u64;
+
+ /// A duration of time, in nanoseconds.
+ type duration = u64;
+
+ /// Read the current value of the clock.
+ ///
+ /// The clock is monotonic, therefore calling this function repeatedly will
+ /// produce a sequence of non-decreasing values.
+ now: func() -> instant;
+
+ /// Query the resolution of the clock. Returns the duration of time
+ /// corresponding to a clock tick.
+ resolution: func() -> duration;
+
+ /// Create a `pollable` which will resolve once the specified instant
+ /// occured.
+ subscribe-instant: func(
+ when: instant,
+ ) -> pollable;
+
+ /// Create a `pollable` which will resolve once the given duration has
+ /// elapsed, starting at the time at which this function was called.
+ /// occured.
+ subscribe-duration: func(
+ when: duration,
+ ) -> pollable;
+}
diff --git a/wit/deps/clocks/wall-clock.wit b/wit/deps/clocks/wall-clock.wit
new file mode 100644
index 0000000..8abb9a0
--- /dev/null
+++ b/wit/deps/clocks/wall-clock.wit
@@ -0,0 +1,42 @@
+package wasi:clocks@0.2.0-rc-2023-11-10;
+/// WASI Wall Clock is a clock API intended to let users query the current
+/// time. The name "wall" makes an analogy to a "clock on the wall", which
+/// is not necessarily monotonic as it may be reset.
+///
+/// It is intended to be portable at least between Unix-family platforms and
+/// Windows.
+///
+/// A wall clock is a clock which measures the date and time according to
+/// some external reference.
+///
+/// External references may be reset, so this clock is not necessarily
+/// monotonic, making it unsuitable for measuring elapsed time.
+///
+/// It is intended for reporting the current date and time for humans.
+interface wall-clock {
+ /// A time and date in seconds plus nanoseconds.
+ record datetime {
+ seconds: u64,
+ nanoseconds: u32,
+ }
+
+ /// Read the current value of the clock.
+ ///
+ /// This clock is not monotonic, therefore calling this function repeatedly
+ /// will not necessarily produce a sequence of non-decreasing values.
+ ///
+ /// The returned timestamps represent the number of seconds since
+ /// 1970-01-01T00:00:00Z, also known as [POSIX's Seconds Since the Epoch],
+ /// also known as [Unix Time].
+ ///
+ /// The nanoseconds field of the output is always less than 1000000000.
+ ///
+ /// [POSIX's Seconds Since the Epoch]: https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xbd_chap04.html#tag_21_04_16
+ /// [Unix Time]: https://en.wikipedia.org/wiki/Unix_time
+ now: func() -> datetime;
+
+ /// Query the resolution of the clock.
+ ///
+ /// The nanoseconds field of the output is always less than 1000000000.
+ resolution: func() -> datetime;
+}
diff --git a/wit/deps/clocks/world.wit b/wit/deps/clocks/world.wit
new file mode 100644
index 0000000..8fa080f
--- /dev/null
+++ b/wit/deps/clocks/world.wit
@@ -0,0 +1,6 @@
+package wasi:clocks@0.2.0-rc-2023-11-10;
+
+world imports {
+ import monotonic-clock;
+ import wall-clock;
+}
diff --git a/wit/deps/io/error.wit b/wit/deps/io/error.wit
new file mode 100644
index 0000000..31918ac
--- /dev/null
+++ b/wit/deps/io/error.wit
@@ -0,0 +1,34 @@
+package wasi:io@0.2.0-rc-2023-11-10;
+
+
+interface error {
+ /// A resource which represents some error information.
+ ///
+ /// The only method provided by this resource is `to-debug-string`,
+ /// which provides some human-readable information about the error.
+ ///
+ /// In the `wasi:io` package, this resource is returned through the
+ /// `wasi:io/streams/stream-error` type.
+ ///
+ /// To provide more specific error information, other interfaces may
+ /// provide functions to further "downcast" this error into more specific
+ /// error information. For example, `error`s returned in streams derived
+ /// from filesystem types to be described using the filesystem's own
+ /// error-code type, using the function
+ /// `wasi:filesystem/types/filesystem-error-code`, which takes a parameter
+ /// `borrow` and returns
+ /// `option`.
+ ///
+ /// The set of functions which can "downcast" an `error` into a more
+ /// concrete type is open.
+ resource error {
+ /// Returns a string that is suitable to assist humans in debugging
+ /// this error.
+ ///
+ /// WARNING: The returned string should not be consumed mechanically!
+ /// It may change across platforms, hosts, or other implementation
+ /// details. Parsing this string is a major platform-compatibility
+ /// hazard.
+ to-debug-string: func() -> string;
+ }
+}
diff --git a/wit/deps/io/poll.wit b/wit/deps/io/poll.wit
index 0829a7d..bddde3c 100644
--- a/wit/deps/io/poll.wit
+++ b/wit/deps/io/poll.wit
@@ -1,4 +1,4 @@
-package wasi:io;
+package wasi:io@0.2.0-rc-2023-11-10;
/// A poll API intended to let users wait for I/O events on multiple handles
/// at once.
diff --git a/wit/deps/io/streams.wit b/wit/deps/io/streams.wit
index 8999b28..e7e1b68 100644
--- a/wit/deps/io/streams.wit
+++ b/wit/deps/io/streams.wit
@@ -1,4 +1,4 @@
-package wasi:io;
+package wasi:io@0.2.0-rc-2023-11-10;
/// WASI I/O is an I/O abstraction API which is currently focused on providing
/// stream types.
@@ -6,6 +6,7 @@ package wasi:io;
/// In the future, the component model is expected to add built-in stream types;
/// when it does, they are expected to subsume this API.
interface streams {
+ use error.{error};
use poll.{pollable};
/// An error for input-stream and output-stream operations.
@@ -20,26 +21,6 @@ interface streams {
closed
}
- /// Contextual error information about the last failure that happened on
- /// a read, write, or flush from an `input-stream` or `output-stream`.
- ///
- /// This type is returned through the `stream-error` type whenever an
- /// operation on a stream directly fails or an error is discovered
- /// after-the-fact, for example when a write's failure shows up through a
- /// later `flush` or `check-write`.
- ///
- /// Interfaces such as `wasi:filesystem/types` provide functionality to
- /// further "downcast" this error into interface-specific error information.
- resource error {
- /// Returns a string that's suitable to assist humans in debugging this
- /// error.
- ///
- /// The returned string will change across platforms and hosts which
- /// means that parsing it, for example, would be a
- /// platform-compatibility hazard.
- to-debug-string: func() -> string;
- }
-
/// An input bytestream.
///
/// `input-stream`s are *non-blocking* to the extent practical on underlying
diff --git a/wit/deps/io/world.wit b/wit/deps/io/world.wit
index 05244a9..8243da2 100644
--- a/wit/deps/io/world.wit
+++ b/wit/deps/io/world.wit
@@ -1,4 +1,4 @@
-package wasi:io;
+package wasi:io@0.2.0-rc-2023-11-10;
world imports {
import streams;
diff --git a/wit/ip-name-lookup.wit b/wit/ip-name-lookup.wit
index 22113ae..931ccf7 100644
--- a/wit/ip-name-lookup.wit
+++ b/wit/ip-name-lookup.wit
@@ -1,50 +1,40 @@
interface ip-name-lookup {
- use wasi:io/poll.{pollable};
- use network.{network, error-code, ip-address, ip-address-family};
+ use wasi:io/poll@0.2.0-rc-2023-11-10.{pollable};
+ use network.{network, error-code, ip-address};
/// Resolve an internet host name to a list of IP addresses.
- ///
+ ///
+ /// Unicode domain names are automatically converted to ASCII using IDNA encoding.
+ /// If the input is an IP address string, the address is parsed and returned
+ /// as-is without making any external requests.
+ ///
/// See the wasi-socket proposal README.md for a comparison with getaddrinfo.
- ///
- /// # Parameters
- /// - `name`: The name to look up. IP addresses are not allowed. Unicode domain names are automatically converted
- /// to ASCII using IDNA encoding.
- /// - `address-family`: If provided, limit the results to addresses of this specific address family.
- /// - `include-unavailable`: When set to true, this function will also return addresses of which the runtime
- /// thinks (or knows) can't be connected to at the moment. For example, this will return IPv6 addresses on
- /// systems without an active IPv6 interface. Notes:
- /// - Even when no public IPv6 interfaces are present or active, names like "localhost" can still resolve to an IPv6 address.
- /// - Whatever is "available" or "unavailable" is volatile and can change everytime a network cable is unplugged.
- ///
- /// This function never blocks. It either immediately fails or immediately returns successfully with a `resolve-address-stream`
- /// that can be used to (asynchronously) fetch the results.
- ///
- /// At the moment, the stream never completes successfully with 0 items. Ie. the first call
- /// to `resolve-next-address` never returns `ok(none)`. This may change in the future.
- ///
+ ///
+ /// This function never blocks. It either immediately fails or immediately
+ /// returns successfully with a `resolve-address-stream` that can be used
+ /// to (asynchronously) fetch the results.
+ ///
/// # Typical errors
- /// - `invalid-name`: `name` is a syntactically invalid domain name.
- /// - `invalid-name`: `name` is an IP address.
- /// - `address-family-not-supported`: The specified `address-family` is not supported. (EAI_FAMILY)
- ///
+ /// - `invalid-argument`: `name` is a syntactically invalid domain name or IP address.
+ ///
/// # References:
/// -
/// -
/// -
/// -
- resolve-addresses: func(network: borrow, name: string, address-family: option, include-unavailable: bool) -> result;
+ resolve-addresses: func(network: borrow, name: string) -> result;
resource resolve-address-stream {
/// Returns the next address from the resolver.
- ///
+ ///
/// This function should be called multiple times. On each call, it will
/// return the next address in connection order preference. If all
/// addresses have been exhausted, this function returns `none`.
- ///
+ ///
/// This function never returns IPv4-mapped IPv6 addresses.
- ///
+ ///
/// # Typical errors
/// - `name-unresolvable`: Name does not exist or has no suitable associated IP addresses. (EAI_NONAME, EAI_NODATA, EAI_ADDRFAMILY)
/// - `temporary-resolver-failure`: A temporary failure in name resolution occurred. (EAI_AGAIN)
@@ -53,7 +43,7 @@ interface ip-name-lookup {
resolve-next-address: func() -> result