Path: blob/main/crates/wasi-common/src/tokio/mod.rs
1692 views
mod dir;1mod file;2pub mod net;3pub mod sched;4pub mod stdio;56use self::sched::sched_ctx;7use crate::sync::net::Socket;8pub use crate::sync::{clocks_ctx, random_ctx};9use crate::{Error, Table, WasiCtx, WasiFile, file::FileAccessMode};10pub use dir::Dir;11pub use file::File;12pub use net::*;13use std::future::Future;14use std::mem;15use std::path::Path;1617pub struct WasiCtxBuilder {18ctx: WasiCtx,19built: bool,20}2122impl WasiCtxBuilder {23pub fn new() -> Self {24WasiCtxBuilder {25ctx: WasiCtx::new(random_ctx(), clocks_ctx(), sched_ctx(), Table::new()),26built: false,27}28}29pub fn env(&mut self, var: &str, value: &str) -> Result<&mut Self, crate::StringArrayError> {30self.ctx.push_env(var, value)?;31Ok(self)32}33pub fn envs(&mut self, env: &[(String, String)]) -> Result<&mut Self, crate::StringArrayError> {34for (k, v) in env {35self.ctx.push_env(k, v)?;36}37Ok(self)38}39pub fn inherit_env(&mut self) -> Result<&mut Self, crate::StringArrayError> {40for (key, value) in std::env::vars() {41self.ctx.push_env(&key, &value)?;42}43Ok(self)44}45pub fn arg(&mut self, arg: &str) -> Result<&mut Self, crate::StringArrayError> {46self.ctx.push_arg(arg)?;47Ok(self)48}49pub fn args(&mut self, arg: &[String]) -> Result<&mut Self, crate::StringArrayError> {50for a in arg {51self.ctx.push_arg(&a)?;52}53Ok(self)54}55pub fn inherit_args(&mut self) -> Result<&mut Self, crate::StringArrayError> {56for arg in std::env::args() {57self.ctx.push_arg(&arg)?;58}59Ok(self)60}61pub fn stdin(&mut self, f: Box<dyn WasiFile>) -> &mut Self {62self.ctx.set_stdin(f);63self64}65pub fn stdout(&mut self, f: Box<dyn WasiFile>) -> &mut Self {66self.ctx.set_stdout(f);67self68}69pub fn stderr(&mut self, f: Box<dyn WasiFile>) -> &mut Self {70self.ctx.set_stderr(f);71self72}73pub fn inherit_stdin(&mut self) -> &mut Self {74self.stdin(Box::new(crate::tokio::stdio::stdin()))75}76pub fn inherit_stdout(&mut self) -> &mut Self {77self.stdout(Box::new(crate::tokio::stdio::stdout()))78}79pub fn inherit_stderr(&mut self) -> &mut Self {80self.stderr(Box::new(crate::tokio::stdio::stderr()))81}82pub fn inherit_stdio(&mut self) -> &mut Self {83self.inherit_stdin().inherit_stdout().inherit_stderr()84}85pub fn preopened_dir(86&mut self,87dir: cap_std::fs::Dir,88guest_path: impl AsRef<Path>,89) -> Result<&mut Self, Error> {90let dir = Box::new(crate::tokio::dir::Dir::from_cap_std(dir));91self.ctx.push_preopened_dir(dir, guest_path)?;92Ok(self)93}94pub fn preopened_socket(95&mut self,96fd: u32,97socket: impl Into<Socket>,98) -> Result<&mut Self, Error> {99let socket: Socket = socket.into();100let file: Box<dyn WasiFile> = socket.into();101self.ctx102.insert_file(fd, file, FileAccessMode::READ | FileAccessMode::WRITE);103Ok(self)104}105106pub fn build(&mut self) -> WasiCtx {107assert!(!self.built);108let WasiCtxBuilder { ctx, .. } = mem::replace(self, Self::new());109self.built = true;110ctx111}112}113114// Much of this mod is implemented in terms of `async` methods from the115// wasmtime_wasi::p2::sync module. These methods may be async in signature, however,116// they are synchronous in implementation (always Poll::Ready on first poll)117// and perform blocking syscalls.118//119// This function takes this blocking code and executes it using a dummy executor120// to assert its immediate readiness. We tell tokio this is a blocking operation121// with the block_in_place function.122pub(crate) fn block_on_dummy_executor<'a, F, Fut, T>(f: F) -> Result<T, Error>123where124F: FnOnce() -> Fut + Send + 'a,125Fut: Future<Output = Result<T, Error>>,126T: Send + 'static,127{128tokio::task::block_in_place(move || {129wiggle::run_in_dummy_executor(f()).expect("wrapped operation should be synchronous")130})131}132133#[cfg(feature = "wasmtime")]134super::define_wasi!(async T: Send);135136137