1pub mod clocks;
18pub mod dir;
19pub mod file;
20pub mod net;
21pub mod sched;
22pub mod stdio;
23
24pub use cap_std::ambient_authority;
25pub use cap_std::fs::Dir;
26pub use cap_std::net::TcpListener;
27pub use clocks::clocks_ctx;
28pub use sched::sched_ctx;
29
30use self::net::Socket;
31use crate::{file::FileAccessMode, table::Table, Error, WasiCtx, WasiFile};
32use cap_rand::{Rng, RngCore, SeedableRng};
33use std::mem;
34use std::path::Path;
35
36pub struct WasiCtxBuilder {
37 ctx: WasiCtx,
38 built: bool,
39}
40
41impl WasiCtxBuilder {
42 pub fn new() -> Self {
43 WasiCtxBuilder {
44 ctx: WasiCtx::new(random_ctx(), clocks_ctx(), sched_ctx(), Table::new()),
45 built: false,
46 }
47 }
48 pub fn env(&mut self, var: &str, value: &str) -> Result<&mut Self, crate::StringArrayError> {
49 self.ctx.push_env(var, value)?;
50 Ok(self)
51 }
52 pub fn envs(&mut self, env: &[(String, String)]) -> Result<&mut Self, crate::StringArrayError> {
53 for (k, v) in env {
54 self.ctx.push_env(k, v)?;
55 }
56 Ok(self)
57 }
58 pub fn inherit_env(&mut self) -> Result<&mut Self, crate::StringArrayError> {
59 for (key, value) in std::env::vars() {
60 self.ctx.push_env(&key, &value)?;
61 }
62 Ok(self)
63 }
64 pub fn arg(&mut self, arg: &str) -> Result<&mut Self, crate::StringArrayError> {
65 self.ctx.push_arg(arg)?;
66 Ok(self)
67 }
68 pub fn args(&mut self, arg: &[String]) -> Result<&mut Self, crate::StringArrayError> {
69 for a in arg {
70 self.ctx.push_arg(&a)?;
71 }
72 Ok(self)
73 }
74 pub fn inherit_args(&mut self) -> Result<&mut Self, crate::StringArrayError> {
75 for arg in std::env::args() {
76 self.ctx.push_arg(&arg)?;
77 }
78 Ok(self)
79 }
80 pub fn stdin(&mut self, f: Box<dyn WasiFile>) -> &mut Self {
81 self.ctx.set_stdin(f);
82 self
83 }
84 pub fn stdout(&mut self, f: Box<dyn WasiFile>) -> &mut Self {
85 self.ctx.set_stdout(f);
86 self
87 }
88 pub fn stderr(&mut self, f: Box<dyn WasiFile>) -> &mut Self {
89 self.ctx.set_stderr(f);
90 self
91 }
92 pub fn inherit_stdin(&mut self) -> &mut Self {
93 self.stdin(Box::new(crate::sync::stdio::stdin()))
94 }
95 pub fn inherit_stdout(&mut self) -> &mut Self {
96 self.stdout(Box::new(crate::sync::stdio::stdout()))
97 }
98 pub fn inherit_stderr(&mut self) -> &mut Self {
99 self.stderr(Box::new(crate::sync::stdio::stderr()))
100 }
101 pub fn inherit_stdio(&mut self) -> &mut Self {
102 self.inherit_stdin().inherit_stdout().inherit_stderr()
103 }
104 pub fn preopened_dir(
105 &mut self,
106 dir: Dir,
107 guest_path: impl AsRef<Path>,
108 ) -> Result<&mut Self, Error> {
109 let dir = Box::new(crate::sync::dir::Dir::from_cap_std(dir));
110 self.ctx.push_preopened_dir(dir, guest_path)?;
111 Ok(self)
112 }
113 pub fn preopened_socket(
114 &mut self,
115 fd: u32,
116 socket: impl Into<Socket>,
117 ) -> Result<&mut Self, Error> {
118 let socket: Socket = socket.into();
119 let file: Box<dyn WasiFile> = socket.into();
120 self.ctx
121 .insert_file(fd, file, FileAccessMode::READ | FileAccessMode::WRITE);
122 Ok(self)
123 }
124 pub fn build(&mut self) -> WasiCtx {
125 assert!(!self.built);
126 let WasiCtxBuilder { ctx, .. } = mem::replace(self, Self::new());
127 self.built = true;
128 ctx
129 }
130}
131
132pub fn random_ctx() -> Box<dyn RngCore + Send + Sync> {
133 let mut rng = cap_rand::thread_rng(cap_rand::ambient_authority());
134 Box::new(cap_rand::rngs::StdRng::from_seed(rng.r#gen()))
135}
136
137#[cfg(feature = "wasmtime")]
138super::define_wasi!(block_on);