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