Files
sausage/userland/brush/probe/src/main.rs
T
surma 665b8a2a03 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).
2026-11-06 17:21:51 +00:00

75 lines
2.5 KiB
Rust

//! Exercises inherited stdio and the service lifecycle through ordinary guest APIs.
use std::io::{Read, Write};
mod bindings {
wit_bindgen::generate!({ path: "../../../host/wit", world: "program", generate_all });
}
use bindings::sausage::process::host::{self, Request, Stdio};
fn mark(path: &str, text: &str) {
let mut file = std::fs::OpenOptions::new()
.create(true)
.append(true)
.open(path)
.unwrap();
writeln!(file, "{text}").unwrap();
}
fn main() {
let args: Vec<_> = std::env::args().collect();
match args.get(1).map(String::as_str) {
Some(mode @ ("inherit" | "identity" | "null")) => {
let io = if mode == "null" {
Stdio::Null
} else {
Stdio::Inherit
};
let child = host::spawn(&Request {
program: args[2].clone(),
argv: args[2..].to_vec(),
cwd: std::env::current_dir().unwrap().to_str().unwrap().into(),
env: std::env::vars().collect(),
group: None,
stdin: io,
stdout: io,
stderr: io,
})
.unwrap();
if mode == "identity" {
println!("parent={}", std::env::var("SAUSAGE_PID").unwrap());
println!("child={}", child.pid());
}
std::process::exit(child.wait());
}
Some("server") => {
mark(&args[2], "start");
let mut input = Vec::new();
std::io::stdin().read_to_end(&mut input).unwrap();
mark(&args[2], "stop");
}
Some("linger") => {
mark(&args[2], "start");
std::thread::sleep(std::time::Duration::from_secs(60));
}
Some("crash") => {
mark(&args[2], "crash");
std::process::exit(1);
}
Some("emit") => {
println!("out");
eprintln!("err");
}
Some("check-null") => {
let mut input = Vec::new();
std::io::stdin().read_to_end(&mut input).unwrap();
assert!(input.is_empty());
println!("out");
eprintln!("err");
}
Some("path") => println!("{}", std::env::var("PATH").unwrap()),
Some("read") => {
let mut input = Vec::new();
std::io::stdin().read_to_end(&mut input).unwrap();
std::io::stdout().write_all(&input).unwrap();
}
_ => println!("pid={}", std::env::var("SAUSAGE_PID").unwrap()),
}
}