host: wasip1 processes, wasi:http, identity, stdio options, services (T12)
- Core modules run on the host-side preview1 over the shared VFS (D41). - wasi:http default handler in the linker; anonymous HTTPS git clone works. Sockets stay denied until P2. - Each process carries the conversation (from Exec, inherited by children, shown in /proc/processes) and a host-assigned SAUSAGE_PID. - Spawn requests choose pipe, inherit or null per stream. - /config/services.yaml supervisor: live edits, restarts, crash limit 5/10 s, graceful stop (stdin EOF, then kill after 5 s) (D44). - Compile caches keyed by content; PATH=/usr/local/bin:/bin. world.rs also carries T13's optional read-only /bin mount (D43).
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
//! Shares process stdio across stores without a parent-side IO pump.
|
||||
use super::bindings::sausage::process::host::Stdio;
|
||||
use std::{
|
||||
pin::Pin,
|
||||
sync::{Arc, Mutex},
|
||||
task::{Context, Poll},
|
||||
};
|
||||
use tokio::io::AsyncWrite;
|
||||
use wasmtime_wasi::cli::{AsyncStdinStream, StdinStream};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub(super) struct Io {
|
||||
pub input: Arc<AsyncStdinStream>,
|
||||
pub output: Writer,
|
||||
pub error: Writer,
|
||||
}
|
||||
impl Io {
|
||||
pub fn input(&self) -> sausage_vfs::preview1::Input {
|
||||
Box::new(Pin::from(self.input.async_stream()))
|
||||
}
|
||||
}
|
||||
#[derive(Clone)]
|
||||
pub(super) struct Writer(Arc<Mutex<Box<dyn AsyncWrite + Send + Sync + Unpin>>>);
|
||||
impl Writer {
|
||||
pub fn new(writer: impl AsyncWrite + Send + Sync + Unpin + 'static) -> Self {
|
||||
Self(Arc::new(Mutex::new(Box::new(writer))))
|
||||
}
|
||||
}
|
||||
impl AsyncWrite for Writer {
|
||||
fn poll_write(
|
||||
self: Pin<&mut Self>,
|
||||
cx: &mut Context<'_>,
|
||||
bytes: &[u8],
|
||||
) -> Poll<std::io::Result<usize>> {
|
||||
Pin::new(&mut **self.0.lock().unwrap()).poll_write(cx, bytes)
|
||||
}
|
||||
fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<std::io::Result<()>> {
|
||||
Pin::new(&mut **self.0.lock().unwrap()).poll_flush(cx)
|
||||
}
|
||||
fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<std::io::Result<()>> {
|
||||
// Closing one inherited handle must not close the other handles.
|
||||
self.poll_flush(cx)
|
||||
}
|
||||
}
|
||||
pub(super) fn input(
|
||||
mode: Stdio,
|
||||
parent: Option<&Io>,
|
||||
) -> (Option<tokio::io::DuplexStream>, Arc<AsyncStdinStream>) {
|
||||
match mode {
|
||||
Stdio::Pipe => {
|
||||
let (host, guest) = tokio::io::duplex(8192);
|
||||
(Some(host), Arc::new(AsyncStdinStream::new(guest)))
|
||||
}
|
||||
Stdio::Inherit => (
|
||||
None,
|
||||
parent.expect("inherit requires a parent").input.clone(),
|
||||
),
|
||||
Stdio::Null => (None, Arc::new(AsyncStdinStream::new(tokio::io::empty()))),
|
||||
}
|
||||
}
|
||||
pub(super) fn output(
|
||||
mode: Stdio,
|
||||
parent: Option<&Writer>,
|
||||
) -> (Option<tokio::io::DuplexStream>, Writer) {
|
||||
match mode {
|
||||
Stdio::Pipe => {
|
||||
let (host, guest) = tokio::io::duplex(8192);
|
||||
(Some(host), Writer::new(guest))
|
||||
}
|
||||
Stdio::Inherit => (None, parent.expect("inherit requires a parent").clone()),
|
||||
Stdio::Null => (None, Writer::new(tokio::io::sink())),
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user