host: process table, shell, coreutils and harness (T8, T9)
T8: sausage:process WIT (spawn, wait, kill), one store per process over the shared root, /proc/processes, /run, pipeline and cancellation groups, Exec. brush and 78 uutils commands; the shared cwd-init object sets the cwd from PWD and keeps numeric exit codes. The corpus matches native bash. T9: V8 (deno_core) runs pi-durable, pi-ai and chord; SQLite storage in <dir>/host/harness.sqlite (WAL, synchronous=FULL); file tools on the VFS, bash through Exec; resumes after SIGKILL.
This commit is contained in:
@@ -0,0 +1,299 @@
|
||||
package wasi:io@0.2.12;
|
||||
|
||||
@since(version = 0.2.0)
|
||||
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
|
||||
/// offer functions to "downcast" this error into more specific types. For example,
|
||||
/// errors returned from streams derived from filesystem types can be described using
|
||||
/// the filesystem's own error-code type. This is done using the function
|
||||
/// `wasi:filesystem/types.filesystem-error-code`, which takes a `borrow<error>`
|
||||
/// parameter and returns an `option<wasi:filesystem/types.error-code>`.
|
||||
///
|
||||
/// The set of functions which can "downcast" an `error` into a more
|
||||
/// concrete type is open.
|
||||
@since(version = 0.2.0)
|
||||
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.
|
||||
@since(version = 0.2.0)
|
||||
to-debug-string: func() -> string;
|
||||
}
|
||||
}
|
||||
|
||||
/// A poll API intended to let users wait for I/O events on multiple handles
|
||||
/// at once.
|
||||
@since(version = 0.2.0)
|
||||
interface poll {
|
||||
/// `pollable` represents a single I/O event which may be ready, or not.
|
||||
@since(version = 0.2.0)
|
||||
resource pollable {
|
||||
/// Return the readiness of a pollable. This function never blocks.
|
||||
///
|
||||
/// Returns `true` when the pollable is ready, and `false` otherwise.
|
||||
@since(version = 0.2.0)
|
||||
ready: func() -> bool;
|
||||
/// `block` returns immediately if the pollable is ready, and otherwise
|
||||
/// blocks until ready.
|
||||
///
|
||||
/// This function is equivalent to calling `poll.poll` on a list
|
||||
/// containing only this pollable.
|
||||
@since(version = 0.2.0)
|
||||
block: func();
|
||||
}
|
||||
|
||||
/// Poll for completion on a set of pollables.
|
||||
///
|
||||
/// This function takes a list of pollables, which identify I/O sources of
|
||||
/// interest, and waits until one or more of the events is ready for I/O.
|
||||
///
|
||||
/// The result `list<u32>` contains one or more indices of handles in the
|
||||
/// argument list that is ready for I/O.
|
||||
///
|
||||
/// This function traps if either:
|
||||
/// - the list is empty, or:
|
||||
/// - the list contains more elements than can be indexed with a `u32` value.
|
||||
///
|
||||
/// A timeout can be implemented by adding a pollable from the
|
||||
/// wasi-clocks API to the list.
|
||||
///
|
||||
/// This function does not return a `result`; polling in itself does not
|
||||
/// do any I/O so it doesn't fail. If any of the I/O sources identified by
|
||||
/// the pollables has an error, it is indicated by marking the source as
|
||||
/// being ready for I/O.
|
||||
@since(version = 0.2.0)
|
||||
poll: func(in: list<borrow<pollable>>) -> list<u32>;
|
||||
}
|
||||
|
||||
/// WASI I/O is an I/O abstraction API which is currently focused on providing
|
||||
/// stream types.
|
||||
///
|
||||
/// In the future, the component model is expected to add built-in stream types;
|
||||
/// when it does, they are expected to subsume this API.
|
||||
@since(version = 0.2.0)
|
||||
interface streams {
|
||||
@since(version = 0.2.0)
|
||||
use error.{error};
|
||||
@since(version = 0.2.0)
|
||||
use poll.{pollable};
|
||||
|
||||
/// An error for input-stream and output-stream operations.
|
||||
@since(version = 0.2.0)
|
||||
variant stream-error {
|
||||
/// The last operation (a write or flush) failed before completion.
|
||||
///
|
||||
/// More information is available in the `error` payload.
|
||||
///
|
||||
/// After this, the stream will be closed. All future operations return
|
||||
/// `stream-error::closed`.
|
||||
last-operation-failed(error),
|
||||
/// The stream is closed: no more input will be accepted by the
|
||||
/// stream. A closed output-stream will return this error on all
|
||||
/// future operations.
|
||||
closed,
|
||||
}
|
||||
|
||||
/// An input bytestream.
|
||||
///
|
||||
/// `input-stream`s are *non-blocking* to the extent practical on underlying
|
||||
/// platforms. I/O operations always return promptly; if fewer bytes are
|
||||
/// promptly available than requested, they return the number of bytes promptly
|
||||
/// available, which could even be zero. To wait for data to be available,
|
||||
/// use the `subscribe` function to obtain a `pollable` which can be polled
|
||||
/// for using `wasi:io/poll`.
|
||||
@since(version = 0.2.0)
|
||||
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
|
||||
/// empty when no bytes are available for reading at this time. The
|
||||
/// pollable given by `subscribe` will be ready when more bytes are
|
||||
/// available.
|
||||
///
|
||||
/// This function fails with a `stream-error` when the operation
|
||||
/// encounters an error, giving `last-operation-failed`, or when the
|
||||
/// stream is closed, giving `closed`.
|
||||
///
|
||||
/// When the caller gives a `len` of 0, it represents a request to
|
||||
/// read 0 bytes. If the stream is still open, this call should
|
||||
/// succeed and return an empty list, or otherwise fail with `closed`.
|
||||
///
|
||||
/// The `len` parameter is a `u64`, which could represent a list of u8 which
|
||||
/// is not possible to allocate in wasm32, or not desirable to allocate as
|
||||
/// as a return value by the callee. The callee may return a list of bytes
|
||||
/// less than `len` in size while more bytes are available for reading.
|
||||
@since(version = 0.2.0)
|
||||
read: func(len: u64) -> result<list<u8>, stream-error>;
|
||||
/// Read bytes from a stream, after blocking until at least one byte can
|
||||
/// be read. Except for blocking, behavior is identical to `read`.
|
||||
@since(version = 0.2.0)
|
||||
blocking-read: func(len: u64) -> result<list<u8>, stream-error>;
|
||||
/// Skip bytes from a stream. Returns number of bytes skipped.
|
||||
///
|
||||
/// Behaves identical to `read`, except instead of returning a list
|
||||
/// of bytes, returns the number of bytes consumed from the stream.
|
||||
@since(version = 0.2.0)
|
||||
skip: func(len: u64) -> result<u64, stream-error>;
|
||||
/// Skip bytes from a stream, after blocking until at least one byte
|
||||
/// can be skipped. Except for blocking behavior, identical to `skip`.
|
||||
@since(version = 0.2.0)
|
||||
blocking-skip: func(len: u64) -> result<u64, stream-error>;
|
||||
/// Create a `pollable` which will resolve once either the specified stream
|
||||
/// has bytes available to read or the other end of the stream has been
|
||||
/// closed.
|
||||
/// The created `pollable` is a child resource of the `input-stream`.
|
||||
/// Implementations may trap if the `input-stream` is dropped before
|
||||
/// all derived `pollable`s created with this function are dropped.
|
||||
@since(version = 0.2.0)
|
||||
subscribe: func() -> pollable;
|
||||
}
|
||||
|
||||
/// An output bytestream.
|
||||
///
|
||||
/// `output-stream`s are *non-blocking* to the extent practical on
|
||||
/// underlying platforms. Except where specified otherwise, I/O operations also
|
||||
/// always return promptly, after the number of bytes that can be written
|
||||
/// promptly, which could even be zero. To wait for the stream to be ready to
|
||||
/// accept data, the `subscribe` function to obtain a `pollable` which can be
|
||||
/// polled for using `wasi:io/poll`.
|
||||
///
|
||||
/// Dropping an `output-stream` while there's still an active write in
|
||||
/// progress may result in the data being lost. Before dropping the stream,
|
||||
/// be sure to fully flush your writes.
|
||||
@since(version = 0.2.0)
|
||||
resource output-stream {
|
||||
/// Check readiness for writing. This function never blocks.
|
||||
///
|
||||
/// Returns the number of bytes permitted for the next call to `write`,
|
||||
/// or an error. Calling `write` with more bytes than this function has
|
||||
/// permitted will trap.
|
||||
///
|
||||
/// When this function returns 0 bytes, the `subscribe` pollable will
|
||||
/// become ready when this function will report at least 1 byte, or an
|
||||
/// error.
|
||||
@since(version = 0.2.0)
|
||||
check-write: func() -> result<u64, stream-error>;
|
||||
/// 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.
|
||||
///
|
||||
/// returns Err(closed) without writing if the stream has closed since
|
||||
/// the last call to check-write provided a permit.
|
||||
@since(version = 0.2.0)
|
||||
write: func(contents: list<u8>) -> result<_, stream-error>;
|
||||
/// Perform a write of up to 4096 bytes, and then flush the stream. Block
|
||||
/// until all of these operations are complete, or an error occurs.
|
||||
///
|
||||
/// Returns success when all of the contents written are successfully
|
||||
/// flushed to output. If an error occurs at any point before all
|
||||
/// contents are successfully flushed, that error is returned as soon as
|
||||
/// possible. If writing and flushing the complete contents causes the
|
||||
/// stream to become closed, this call should return success, and
|
||||
/// subsequent calls to check-write or other interfaces should return
|
||||
/// stream-error::closed.
|
||||
@since(version = 0.2.0)
|
||||
blocking-write-and-flush: func(contents: list<u8>) -> result<_, stream-error>;
|
||||
/// Request to flush buffered output. This function never blocks.
|
||||
///
|
||||
/// This tells the output-stream that the caller intends any buffered
|
||||
/// output to be flushed. the output which is expected to be flushed
|
||||
/// is all that has been passed to `write` prior to this call.
|
||||
///
|
||||
/// Upon calling this function, the `output-stream` will not accept any
|
||||
/// writes (`check-write` will return `ok(0)`) until the flush has
|
||||
/// completed. The `subscribe` pollable will become ready when the
|
||||
/// flush has completed and the stream can accept more writes.
|
||||
@since(version = 0.2.0)
|
||||
flush: func() -> result<_, stream-error>;
|
||||
/// Request to flush buffered output, and block until flush completes
|
||||
/// and stream is ready for writing again.
|
||||
@since(version = 0.2.0)
|
||||
blocking-flush: func() -> result<_, stream-error>;
|
||||
/// Create a `pollable` which will resolve once the output-stream
|
||||
/// is ready for more writing, or an error has occurred. When this
|
||||
/// pollable is ready, `check-write` will return `ok(n)` with n>0, or an
|
||||
/// error.
|
||||
///
|
||||
/// If the stream is closed, this pollable is always ready immediately.
|
||||
///
|
||||
/// The created `pollable` is a child resource of the `output-stream`.
|
||||
/// Implementations may trap if the `output-stream` is dropped before
|
||||
/// all derived `pollable`s created with this function are dropped.
|
||||
@since(version = 0.2.0)
|
||||
subscribe: func() -> pollable;
|
||||
/// Write zeroes to a stream.
|
||||
///
|
||||
/// 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.
|
||||
@since(version = 0.2.0)
|
||||
write-zeroes: func(len: u64) -> result<_, stream-error>;
|
||||
/// Perform a write of up to 4096 zeroes, and then flush the stream.
|
||||
/// Block until all of these operations are complete, or an error
|
||||
/// occurs.
|
||||
///
|
||||
/// Functionality is equivelant to `blocking-write-and-flush` with
|
||||
/// contents given as a list of len containing only zeroes.
|
||||
@since(version = 0.2.0)
|
||||
blocking-write-zeroes-and-flush: func(len: u64) -> result<_, stream-error>;
|
||||
/// Read from one stream and write to another.
|
||||
///
|
||||
/// The behavior of splice is equivalent to:
|
||||
/// 1. calling `check-write` on the `output-stream`
|
||||
/// 2. calling `read` on the `input-stream` with the smaller of the
|
||||
/// `check-write` permitted length and the `len` provided to `splice`
|
||||
/// 3. calling `write` on the `output-stream` with that read data.
|
||||
///
|
||||
/// Any error reported by the call to `check-write`, `read`, or
|
||||
/// `write` ends the splice and reports that error.
|
||||
///
|
||||
/// This function returns the number of bytes transferred; it may be less
|
||||
/// than `len`.
|
||||
@since(version = 0.2.0)
|
||||
splice: func(src: borrow<input-stream>, len: u64) -> result<u64, stream-error>;
|
||||
/// Read from one stream and write to another, with blocking.
|
||||
///
|
||||
/// This is similar to `splice`, except that it blocks until the
|
||||
/// `output-stream` is ready for writing, and the `input-stream`
|
||||
/// is ready for reading, before performing the `splice`.
|
||||
@since(version = 0.2.0)
|
||||
blocking-splice: func(src: borrow<input-stream>, len: u64) -> result<u64, stream-error>;
|
||||
}
|
||||
}
|
||||
|
||||
@since(version = 0.2.0)
|
||||
world imports {
|
||||
@since(version = 0.2.0)
|
||||
import error;
|
||||
@since(version = 0.2.0)
|
||||
import poll;
|
||||
@since(version = 0.2.0)
|
||||
import streams;
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package sausage:process@0.1.0;
|
||||
|
||||
/// Programs share one world. These resources provide lifecycle and bounded stdio transport.
|
||||
interface host {
|
||||
use wasi:io/streams@0.2.12.{input-stream, output-stream};
|
||||
record request {
|
||||
program: string,
|
||||
argv: list<string>,
|
||||
env: list<tuple<string, string>>,
|
||||
cwd: string,
|
||||
/// None inherits the parent's group. Zero creates a group. A nonzero ID joins a group.
|
||||
group: option<u32>,
|
||||
}
|
||||
resource child {
|
||||
pid: func() -> u32;
|
||||
group: func() -> u32;
|
||||
stdin: func() -> output-stream;
|
||||
stdout: func() -> input-stream;
|
||||
stderr: func() -> input-stream;
|
||||
status: func() -> option<s32>;
|
||||
wait: func() -> s32;
|
||||
kill: func();
|
||||
}
|
||||
spawn: func(request: request) -> result<child, string>;
|
||||
kill: func(pid: u32) -> result<_, string>;
|
||||
}
|
||||
world program {
|
||||
import host;
|
||||
}
|
||||
Reference in New Issue
Block a user