Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bytecodealliance
GitHub Repository: bytecodealliance/wasmtime
Path: blob/main/crates/wasi-common/src/ctx.rs
1691 views
1
use crate::clocks::WasiClocks;
2
use crate::dir::{DirEntry, WasiDir};
3
use crate::file::{FileAccessMode, FileEntry, WasiFile};
4
use crate::sched::WasiSched;
5
use crate::string_array::StringArray;
6
use crate::table::Table;
7
use crate::{Error, StringArrayError};
8
use cap_rand::RngCore;
9
use std::ops::Deref;
10
use std::path::{Path, PathBuf};
11
use std::sync::{Arc, Mutex};
12
13
/// An `Arc`-wrapper around the wasi-common context to allow mutable access to
14
/// the file descriptor table. This wrapper is only necessary due to the
15
/// signature of `fd_fdstat_set_flags`; if that changes, there are a variety of
16
/// improvements that can be made (TODO:
17
/// <https://github.com/bytecodealliance/wasmtime/issues/5643)>.
18
#[derive(Clone)]
19
pub struct WasiCtx(Arc<WasiCtxInner>);
20
21
pub struct WasiCtxInner {
22
pub args: StringArray,
23
pub env: StringArray,
24
// TODO: this mutex should not be necessary, it forces threads to serialize
25
// their access to randomness unnecessarily
26
// (https://github.com/bytecodealliance/wasmtime/issues/5660).
27
pub random: Mutex<Box<dyn RngCore + Send + Sync>>,
28
pub clocks: WasiClocks,
29
pub sched: Box<dyn WasiSched>,
30
pub table: Table,
31
}
32
33
impl WasiCtx {
34
pub fn new(
35
random: Box<dyn RngCore + Send + Sync>,
36
clocks: WasiClocks,
37
sched: Box<dyn WasiSched>,
38
table: Table,
39
) -> Self {
40
let s = WasiCtx(Arc::new(WasiCtxInner {
41
args: StringArray::new(),
42
env: StringArray::new(),
43
random: Mutex::new(random),
44
clocks,
45
sched,
46
table,
47
}));
48
s.set_stdin(Box::new(crate::pipe::ReadPipe::new(std::io::empty())));
49
s.set_stdout(Box::new(crate::pipe::WritePipe::new(std::io::sink())));
50
s.set_stderr(Box::new(crate::pipe::WritePipe::new(std::io::sink())));
51
s
52
}
53
54
pub fn insert_file(&self, fd: u32, file: Box<dyn WasiFile>, access_mode: FileAccessMode) {
55
self.table()
56
.insert_at(fd, Arc::new(FileEntry::new(file, access_mode)));
57
}
58
59
pub fn push_file(
60
&self,
61
file: Box<dyn WasiFile>,
62
access_mode: FileAccessMode,
63
) -> Result<u32, Error> {
64
self.table()
65
.push(Arc::new(FileEntry::new(file, access_mode)))
66
}
67
68
pub fn insert_dir(&self, fd: u32, dir: Box<dyn WasiDir>, path: PathBuf) {
69
self.table()
70
.insert_at(fd, Arc::new(DirEntry::new(Some(path), dir)));
71
}
72
73
pub fn push_dir(&self, dir: Box<dyn WasiDir>, path: PathBuf) -> Result<u32, Error> {
74
self.table().push(Arc::new(DirEntry::new(Some(path), dir)))
75
}
76
77
pub fn table(&self) -> &Table {
78
&self.table
79
}
80
81
pub fn table_mut(&mut self) -> Option<&mut Table> {
82
Arc::get_mut(&mut self.0).map(|c| &mut c.table)
83
}
84
85
pub fn push_arg(&mut self, arg: &str) -> Result<(), StringArrayError> {
86
let s = Arc::get_mut(&mut self.0).expect(
87
"`push_arg` should only be used during initialization before the context is cloned",
88
);
89
s.args.push(arg.to_owned())
90
}
91
92
pub fn push_env(&mut self, var: &str, value: &str) -> Result<(), StringArrayError> {
93
let s = Arc::get_mut(&mut self.0).expect(
94
"`push_env` should only be used during initialization before the context is cloned",
95
);
96
s.env.push(format!("{var}={value}"))?;
97
Ok(())
98
}
99
100
pub fn set_stdin(&self, f: Box<dyn WasiFile>) {
101
self.insert_file(0, f, FileAccessMode::READ);
102
}
103
104
pub fn set_stdout(&self, f: Box<dyn WasiFile>) {
105
self.insert_file(1, f, FileAccessMode::WRITE);
106
}
107
108
pub fn set_stderr(&self, f: Box<dyn WasiFile>) {
109
self.insert_file(2, f, FileAccessMode::WRITE);
110
}
111
112
pub fn push_preopened_dir(
113
&self,
114
dir: Box<dyn WasiDir>,
115
path: impl AsRef<Path>,
116
) -> Result<(), Error> {
117
self.table()
118
.push(Arc::new(DirEntry::new(Some(path.as_ref().to_owned()), dir)))?;
119
Ok(())
120
}
121
}
122
123
impl Deref for WasiCtx {
124
type Target = WasiCtxInner;
125
fn deref(&self) -> &Self::Target {
126
&self.0
127
}
128
}
129
130