/src/wasmtime/crates/wasi/src/ctx.rs
Line | Count | Source |
1 | | use crate::cli::{StdinStream, StdoutStream, WasiCliCtx}; |
2 | | use crate::clocks::{HostMonotonicClock, HostWallClock, WasiClocksCtx}; |
3 | | use crate::filesystem::{Dir, WasiFilesystemCtx}; |
4 | | use crate::random::WasiRandomCtx; |
5 | | use crate::sockets::{SocketAddrCheck, SocketAddrUse, WasiSocketsCtx}; |
6 | | use crate::{DirPerms, FilePerms, OpenMode}; |
7 | | use cap_rand::RngCore; |
8 | | use cap_std::ambient_authority; |
9 | | use std::future::Future; |
10 | | use std::mem; |
11 | | use std::net::SocketAddr; |
12 | | use std::path::Path; |
13 | | use std::pin::Pin; |
14 | | use tokio::io::{stderr, stdin, stdout}; |
15 | | use wasmtime::Result; |
16 | | |
17 | | /// Builder-style structure used to create a [`WasiCtx`]. |
18 | | /// |
19 | | /// This type is used to create a [`WasiCtx`] that is considered per-[`Store`] |
20 | | /// state. The [`build`][WasiCtxBuilder::build] method is used to finish the |
21 | | /// building process and produce a finalized [`WasiCtx`]. |
22 | | /// |
23 | | /// # Examples |
24 | | /// |
25 | | /// ``` |
26 | | /// use wasmtime_wasi::WasiCtx; |
27 | | /// |
28 | | /// let mut wasi = WasiCtx::builder(); |
29 | | /// wasi.arg("./foo.wasm"); |
30 | | /// wasi.arg("--help"); |
31 | | /// wasi.env("FOO", "bar"); |
32 | | /// |
33 | | /// let wasi: WasiCtx = wasi.build(); |
34 | | /// ``` |
35 | | /// |
36 | | /// [`Store`]: wasmtime::Store |
37 | | #[derive(Default)] |
38 | | pub struct WasiCtxBuilder { |
39 | | cli: WasiCliCtx, |
40 | | clocks: WasiClocksCtx, |
41 | | filesystem: WasiFilesystemCtx, |
42 | | random: WasiRandomCtx, |
43 | | sockets: WasiSocketsCtx, |
44 | | built: bool, |
45 | | } |
46 | | |
47 | | impl WasiCtxBuilder { |
48 | | /// Creates a builder for a new context with default parameters set. |
49 | | /// |
50 | | /// The current defaults are: |
51 | | /// |
52 | | /// * stdin is closed |
53 | | /// * stdout and stderr eat all input and it doesn't go anywhere |
54 | | /// * no env vars |
55 | | /// * no arguments |
56 | | /// * no preopens |
57 | | /// * clocks use the host implementation of wall/monotonic clocks |
58 | | /// * RNGs are all initialized with random state and suitable generator |
59 | | /// quality to satisfy the requirements of WASI APIs. |
60 | | /// * TCP/UDP are allowed but all addresses are denied by default. |
61 | | /// * `wasi:sockets/ip-name-lookup` is denied by default. |
62 | | /// |
63 | | /// These defaults can all be updated via the various builder configuration |
64 | | /// methods below. |
65 | 0 | pub fn new() -> Self { |
66 | 0 | Self::default() |
67 | 0 | } |
68 | | |
69 | | /// Provides a custom implementation of stdin to use. |
70 | | /// |
71 | | /// By default stdin is closed but an example of using the host's native |
72 | | /// stdin looks like: |
73 | | /// |
74 | | /// ``` |
75 | | /// use wasmtime_wasi::WasiCtx; |
76 | | /// use wasmtime_wasi::cli::stdin; |
77 | | /// |
78 | | /// let mut wasi = WasiCtx::builder(); |
79 | | /// wasi.stdin(stdin()); |
80 | | /// ``` |
81 | | /// |
82 | | /// Note that inheriting the process's stdin can also be done through |
83 | | /// [`inherit_stdin`](WasiCtxBuilder::inherit_stdin). |
84 | 0 | pub fn stdin(&mut self, stdin: impl StdinStream + 'static) -> &mut Self { |
85 | 0 | self.cli.stdin = Box::new(stdin); |
86 | 0 | self |
87 | 0 | } |
88 | | |
89 | | /// Same as [`stdin`](WasiCtxBuilder::stdin), but for stdout. |
90 | 0 | pub fn stdout(&mut self, stdout: impl StdoutStream + 'static) -> &mut Self { |
91 | 0 | self.cli.stdout = Box::new(stdout); |
92 | 0 | self |
93 | 0 | } |
94 | | |
95 | | /// Same as [`stdin`](WasiCtxBuilder::stdin), but for stderr. |
96 | 0 | pub fn stderr(&mut self, stderr: impl StdoutStream + 'static) -> &mut Self { |
97 | 0 | self.cli.stderr = Box::new(stderr); |
98 | 0 | self |
99 | 0 | } |
100 | | |
101 | | /// Configures this context's stdin stream to read the host process's |
102 | | /// stdin. |
103 | | /// |
104 | | /// Note that concurrent reads of stdin can produce surprising results so |
105 | | /// when using this it's typically best to have a single wasm instance in |
106 | | /// the process using this. |
107 | 0 | pub fn inherit_stdin(&mut self) -> &mut Self { |
108 | 0 | self.stdin(stdin()) |
109 | 0 | } |
110 | | |
111 | | /// Configures this context's stdout stream to write to the host process's |
112 | | /// stdout. |
113 | | /// |
114 | | /// Note that unlike [`inherit_stdin`](WasiCtxBuilder::inherit_stdin) |
115 | | /// multiple instances printing to stdout works well. |
116 | 0 | pub fn inherit_stdout(&mut self) -> &mut Self { |
117 | 0 | self.stdout(stdout()) |
118 | 0 | } |
119 | | |
120 | | /// Configures this context's stderr stream to write to the host process's |
121 | | /// stderr. |
122 | | /// |
123 | | /// Note that unlike [`inherit_stdin`](WasiCtxBuilder::inherit_stdin) |
124 | | /// multiple instances printing to stderr works well. |
125 | 0 | pub fn inherit_stderr(&mut self) -> &mut Self { |
126 | 0 | self.stderr(stderr()) |
127 | 0 | } |
128 | | |
129 | | /// Configures all of stdin, stdout, and stderr to be inherited from the |
130 | | /// host process. |
131 | | /// |
132 | | /// See [`inherit_stdin`](WasiCtxBuilder::inherit_stdin) for some rationale |
133 | | /// on why this should only be done in situations of |
134 | | /// one-instance-per-process. |
135 | 0 | pub fn inherit_stdio(&mut self) -> &mut Self { |
136 | 0 | self.inherit_stdin().inherit_stdout().inherit_stderr() |
137 | 0 | } |
138 | | |
139 | | /// Configures whether or not blocking operations made through this |
140 | | /// `WasiCtx` are allowed to block the current thread. |
141 | | /// |
142 | | /// WASI is currently implemented on top of the Rust |
143 | | /// [Tokio](https://tokio.rs/) library. While most WASI APIs are |
144 | | /// non-blocking some are instead blocking from the perspective of |
145 | | /// WebAssembly. For example opening a file is a blocking operation with |
146 | | /// respect to WebAssembly but it's implemented as an asynchronous operation |
147 | | /// on the host. This is currently done with Tokio's |
148 | | /// [`spawn_blocking`](https://docs.rs/tokio/latest/tokio/task/fn.spawn_blocking.html). |
149 | | /// |
150 | | /// When WebAssembly is used in a synchronous context, for example when |
151 | | /// [`Config::async_support`] is disabled, then this asynchronous operation |
152 | | /// is quickly turned back into a synchronous operation with a `block_on` in |
153 | | /// Rust. This switching back-and-forth between a blocking a non-blocking |
154 | | /// context can have overhead, and this option exists to help alleviate this |
155 | | /// overhead. |
156 | | /// |
157 | | /// This option indicates that for WASI functions that are blocking from the |
158 | | /// perspective of WebAssembly it's ok to block the native thread as well. |
159 | | /// This means that this back-and-forth between async and sync won't happen |
160 | | /// and instead blocking operations are performed on-thread (such as opening |
161 | | /// a file). This can improve the performance of WASI operations when async |
162 | | /// support is disabled. |
163 | | /// |
164 | | /// [`Config::async_support`]: https://docs.rs/wasmtime/latest/wasmtime/struct.Config.html#method.async_support |
165 | 0 | pub fn allow_blocking_current_thread(&mut self, enable: bool) -> &mut Self { |
166 | 0 | self.filesystem.allow_blocking_current_thread = enable; |
167 | 0 | self |
168 | 0 | } |
169 | | |
170 | | /// Appends multiple environment variables at once for this builder. |
171 | | /// |
172 | | /// All environment variables are appended to the list of environment |
173 | | /// variables that this builder will configure. |
174 | | /// |
175 | | /// At this time environment variables are not deduplicated and if the same |
176 | | /// key is set twice then the guest will see two entries for the same key. |
177 | | /// |
178 | | /// # Examples |
179 | | /// |
180 | | /// ``` |
181 | | /// use wasmtime_wasi::WasiCtxBuilder; |
182 | | /// |
183 | | /// let mut wasi = WasiCtxBuilder::new(); |
184 | | /// wasi.envs(&[ |
185 | | /// ("FOO", "bar"), |
186 | | /// ("HOME", "/somewhere"), |
187 | | /// ]); |
188 | | /// ``` |
189 | 0 | pub fn envs(&mut self, env: &[(impl AsRef<str>, impl AsRef<str>)]) -> &mut Self { |
190 | 0 | self.cli.environment.extend( |
191 | 0 | env.iter() |
192 | 0 | .map(|(k, v)| (k.as_ref().to_owned(), v.as_ref().to_owned())), |
193 | | ); |
194 | 0 | self |
195 | 0 | } |
196 | | |
197 | | /// Appends a single environment variable for this builder. |
198 | | /// |
199 | | /// At this time environment variables are not deduplicated and if the same |
200 | | /// key is set twice then the guest will see two entries for the same key. |
201 | | /// |
202 | | /// # Examples |
203 | | /// |
204 | | /// ``` |
205 | | /// use wasmtime_wasi::WasiCtxBuilder; |
206 | | /// |
207 | | /// let mut wasi = WasiCtxBuilder::new(); |
208 | | /// wasi.env("FOO", "bar"); |
209 | | /// ``` |
210 | 0 | pub fn env(&mut self, k: impl AsRef<str>, v: impl AsRef<str>) -> &mut Self { |
211 | 0 | self.cli |
212 | 0 | .environment |
213 | 0 | .push((k.as_ref().to_owned(), v.as_ref().to_owned())); |
214 | 0 | self |
215 | 0 | } |
216 | | |
217 | | /// Configures all environment variables to be inherited from the calling |
218 | | /// process into this configuration. |
219 | | /// |
220 | | /// This will use [`envs`](WasiCtxBuilder::envs) to append all host-defined |
221 | | /// environment variables. |
222 | 0 | pub fn inherit_env(&mut self) -> &mut Self { |
223 | 0 | self.envs(&std::env::vars().collect::<Vec<(String, String)>>()) |
224 | 0 | } |
225 | | |
226 | | /// Appends a list of arguments to the argument array to pass to wasm. |
227 | 0 | pub fn args(&mut self, args: &[impl AsRef<str>]) -> &mut Self { |
228 | 0 | self.cli |
229 | 0 | .arguments |
230 | 0 | .extend(args.iter().map(|a| a.as_ref().to_owned())); |
231 | 0 | self |
232 | 0 | } |
233 | | |
234 | | /// Appends a single argument to get passed to wasm. |
235 | 0 | pub fn arg(&mut self, arg: impl AsRef<str>) -> &mut Self { |
236 | 0 | self.cli.arguments.push(arg.as_ref().to_owned()); |
237 | 0 | self |
238 | 0 | } |
239 | | |
240 | | /// Appends all host process arguments to the list of arguments to get |
241 | | /// passed to wasm. |
242 | 0 | pub fn inherit_args(&mut self) -> &mut Self { |
243 | 0 | self.args(&std::env::args().collect::<Vec<String>>()) |
244 | 0 | } |
245 | | |
246 | | /// Configures a "preopened directory" to be available to WebAssembly. |
247 | | /// |
248 | | /// By default WebAssembly does not have access to the filesystem because |
249 | | /// there are no preopened directories. All filesystem operations, such as |
250 | | /// opening a file, are done through a preexisting handle. This means that |
251 | | /// to provide WebAssembly access to a directory it must be configured |
252 | | /// through this API. |
253 | | /// |
254 | | /// WASI will also prevent access outside of files provided here. For |
255 | | /// example `..` can't be used to traverse up from the `host_path` provided here |
256 | | /// to the containing directory. |
257 | | /// |
258 | | /// * `host_path` - a path to a directory on the host to open and make |
259 | | /// accessible to WebAssembly. Note that the name of this directory in the |
260 | | /// guest is configured with `guest_path` below. |
261 | | /// * `guest_path` - the name of the preopened directory from WebAssembly's |
262 | | /// perspective. Note that this does not need to match the host's name for |
263 | | /// the directory. |
264 | | /// * `dir_perms` - this is the permissions that wasm will have to operate on |
265 | | /// `guest_path`. This can be used, for example, to provide readonly access to a |
266 | | /// directory. |
267 | | /// * `file_perms` - similar to `dir_perms` but corresponds to the maximum set |
268 | | /// of permissions that can be used for any file in this directory. |
269 | | /// |
270 | | /// # Errors |
271 | | /// |
272 | | /// This method will return an error if `host_path` cannot be opened. |
273 | | /// |
274 | | /// # Examples |
275 | | /// |
276 | | /// ``` |
277 | | /// use wasmtime_wasi::WasiCtxBuilder; |
278 | | /// use wasmtime_wasi::{DirPerms, FilePerms}; |
279 | | /// |
280 | | /// # fn main() {} |
281 | | /// # fn foo() -> wasmtime::Result<()> { |
282 | | /// let mut wasi = WasiCtxBuilder::new(); |
283 | | /// |
284 | | /// // Make `./host-directory` available in the guest as `.` |
285 | | /// wasi.preopened_dir("./host-directory", ".", DirPerms::all(), FilePerms::all()); |
286 | | /// |
287 | | /// // Make `./readonly` available in the guest as `./ro` |
288 | | /// wasi.preopened_dir("./readonly", "./ro", DirPerms::READ, FilePerms::READ); |
289 | | /// # Ok(()) |
290 | | /// # } |
291 | | /// ``` |
292 | 0 | pub fn preopened_dir( |
293 | 0 | &mut self, |
294 | 0 | host_path: impl AsRef<Path>, |
295 | 0 | guest_path: impl AsRef<str>, |
296 | 0 | dir_perms: DirPerms, |
297 | 0 | file_perms: FilePerms, |
298 | 0 | ) -> Result<&mut Self> { |
299 | 0 | let dir = cap_std::fs::Dir::open_ambient_dir(host_path.as_ref(), ambient_authority())?; |
300 | 0 | let mut open_mode = OpenMode::empty(); |
301 | 0 | if dir_perms.contains(DirPerms::READ) { |
302 | 0 | open_mode |= OpenMode::READ; |
303 | 0 | } |
304 | 0 | if dir_perms.contains(DirPerms::MUTATE) { |
305 | 0 | open_mode |= OpenMode::WRITE; |
306 | 0 | } |
307 | 0 | self.filesystem.preopens.push(( |
308 | 0 | Dir::new( |
309 | 0 | dir, |
310 | 0 | dir_perms, |
311 | 0 | file_perms, |
312 | 0 | open_mode, |
313 | 0 | self.filesystem.allow_blocking_current_thread, |
314 | 0 | ), |
315 | 0 | guest_path.as_ref().to_owned(), |
316 | 0 | )); |
317 | 0 | Ok(self) |
318 | 0 | } |
319 | | |
320 | | /// Set the generator for the `wasi:random/random` number generator to the |
321 | | /// custom generator specified. |
322 | | /// |
323 | | /// Note that contexts have a default RNG configured which is a suitable |
324 | | /// generator for WASI and is configured with a random seed per-context. |
325 | | /// |
326 | | /// Guest code may rely on this random number generator to produce fresh |
327 | | /// unpredictable random data in order to maintain its security invariants, |
328 | | /// and ideally should use the insecure random API otherwise, so using any |
329 | | /// prerecorded or otherwise predictable data may compromise security. |
330 | 0 | pub fn secure_random(&mut self, random: impl RngCore + Send + 'static) -> &mut Self { |
331 | 0 | self.random.random = Box::new(random); |
332 | 0 | self |
333 | 0 | } |
334 | | |
335 | | /// Configures the generator for `wasi:random/insecure`. |
336 | | /// |
337 | | /// The `insecure_random` generator provided will be used for all randomness |
338 | | /// requested by the `wasi:random/insecure` interface. |
339 | 0 | pub fn insecure_random(&mut self, insecure_random: impl RngCore + Send + 'static) -> &mut Self { |
340 | 0 | self.random.insecure_random = Box::new(insecure_random); |
341 | 0 | self |
342 | 0 | } |
343 | | |
344 | | /// Configures the seed to be returned from `wasi:random/insecure-seed` to |
345 | | /// the specified custom value. |
346 | | /// |
347 | | /// By default this number is randomly generated when a builder is created. |
348 | 0 | pub fn insecure_random_seed(&mut self, insecure_random_seed: u128) -> &mut Self { |
349 | 0 | self.random.insecure_random_seed = insecure_random_seed; |
350 | 0 | self |
351 | 0 | } |
352 | | |
353 | | /// Configures `wasi:clocks/wall-clock` to use the `clock` specified. |
354 | | /// |
355 | | /// By default the host's wall clock is used. |
356 | 0 | pub fn wall_clock(&mut self, clock: impl HostWallClock + 'static) -> &mut Self { |
357 | 0 | self.clocks.wall_clock = Box::new(clock); |
358 | 0 | self |
359 | 0 | } |
360 | | |
361 | | /// Configures `wasi:clocks/monotonic-clock` to use the `clock` specified. |
362 | | /// |
363 | | /// By default the host's monotonic clock is used. |
364 | 0 | pub fn monotonic_clock(&mut self, clock: impl HostMonotonicClock + 'static) -> &mut Self { |
365 | 0 | self.clocks.monotonic_clock = Box::new(clock); |
366 | 0 | self |
367 | 0 | } |
368 | | |
369 | | /// Allow all network addresses accessible to the host. |
370 | | /// |
371 | | /// This method will inherit all network addresses meaning that any address |
372 | | /// can be bound by the guest or connected to by the guest using any |
373 | | /// protocol. |
374 | | /// |
375 | | /// See also [`WasiCtxBuilder::socket_addr_check`]. |
376 | 0 | pub fn inherit_network(&mut self) -> &mut Self { |
377 | 0 | self.socket_addr_check(|_, _| Box::pin(async { true })) |
378 | 0 | } |
379 | | |
380 | | /// A check that will be called for each socket address that is used. |
381 | | /// |
382 | | /// Returning `true` will permit socket connections to the `SocketAddr`, |
383 | | /// while returning `false` will reject the connection. |
384 | 0 | pub fn socket_addr_check<F>(&mut self, check: F) -> &mut Self |
385 | 0 | where |
386 | 0 | F: Fn(SocketAddr, SocketAddrUse) -> Pin<Box<dyn Future<Output = bool> + Send + Sync>> |
387 | 0 | + Send |
388 | 0 | + Sync |
389 | 0 | + 'static, |
390 | | { |
391 | 0 | self.sockets.socket_addr_check = SocketAddrCheck::new(check); |
392 | 0 | self |
393 | 0 | } |
394 | | |
395 | | /// Allow usage of `wasi:sockets/ip-name-lookup` |
396 | | /// |
397 | | /// By default this is disabled. |
398 | 0 | pub fn allow_ip_name_lookup(&mut self, enable: bool) -> &mut Self { |
399 | 0 | self.sockets.allowed_network_uses.ip_name_lookup = enable; |
400 | 0 | self |
401 | 0 | } |
402 | | |
403 | | /// Allow usage of UDP. |
404 | | /// |
405 | | /// This is enabled by default, but can be disabled if UDP should be blanket |
406 | | /// disabled. |
407 | 0 | pub fn allow_udp(&mut self, enable: bool) -> &mut Self { |
408 | 0 | self.sockets.allowed_network_uses.udp = enable; |
409 | 0 | self |
410 | 0 | } |
411 | | |
412 | | /// Allow usage of TCP |
413 | | /// |
414 | | /// This is enabled by default, but can be disabled if TCP should be blanket |
415 | | /// disabled. |
416 | 0 | pub fn allow_tcp(&mut self, enable: bool) -> &mut Self { |
417 | 0 | self.sockets.allowed_network_uses.tcp = enable; |
418 | 0 | self |
419 | 0 | } |
420 | | |
421 | | /// Uses the configured context so far to construct the final [`WasiCtx`]. |
422 | | /// |
423 | | /// Note that each `WasiCtxBuilder` can only be used to "build" once, and |
424 | | /// calling this method twice will panic. |
425 | | /// |
426 | | /// # Panics |
427 | | /// |
428 | | /// Panics if this method is called twice. Each [`WasiCtxBuilder`] can be |
429 | | /// used to create only a single [`WasiCtx`]. Repeated usage of this method |
430 | | /// is not allowed and should use a second builder instead. |
431 | 0 | pub fn build(&mut self) -> WasiCtx { |
432 | 0 | assert!(!self.built); |
433 | | |
434 | | let Self { |
435 | 0 | cli, |
436 | 0 | clocks, |
437 | 0 | filesystem, |
438 | 0 | random, |
439 | 0 | sockets, |
440 | | built: _, |
441 | 0 | } = mem::replace(self, Self::new()); |
442 | 0 | self.built = true; |
443 | | |
444 | 0 | WasiCtx { |
445 | 0 | cli, |
446 | 0 | clocks, |
447 | 0 | filesystem, |
448 | 0 | random, |
449 | 0 | sockets, |
450 | 0 | } |
451 | 0 | } |
452 | | /// Builds a WASIp1 context instead of a [`WasiCtx`]. |
453 | | /// |
454 | | /// This method is the same as [`build`](WasiCtxBuilder::build) but it |
455 | | /// creates a [`WasiP1Ctx`] instead. This is intended for use with the |
456 | | /// [`p1`] module of this crate |
457 | | /// |
458 | | /// [`WasiP1Ctx`]: crate::p1::WasiP1Ctx |
459 | | /// [`p1`]: crate::p1 |
460 | | /// |
461 | | /// # Panics |
462 | | /// |
463 | | /// Panics if this method is called twice. Each [`WasiCtxBuilder`] can be |
464 | | /// used to create only a single [`WasiCtx`] or [`WasiP1Ctx`]. Repeated |
465 | | /// usage of this method is not allowed and should use a second builder |
466 | | /// instead. |
467 | | #[cfg(feature = "p1")] |
468 | | pub fn build_p1(&mut self) -> crate::p1::WasiP1Ctx { |
469 | | let wasi = self.build(); |
470 | | crate::p1::WasiP1Ctx::new(wasi) |
471 | | } |
472 | | } |
473 | | |
474 | | /// Per-[`Store`] state which holds state necessary to implement WASI from this |
475 | | /// crate. |
476 | | /// |
477 | | /// This structure is created through [`WasiCtxBuilder`] and is stored within |
478 | | /// the `T` of [`Store<T>`][`Store`]. Access to the structure is provided |
479 | | /// through the [`WasiView`](crate::WasiView) trait as an implementation on `T`. |
480 | | /// |
481 | | /// Note that this structure itself does not have any accessors, it's here for |
482 | | /// internal use within the `wasmtime-wasi` crate's implementation of |
483 | | /// bindgen-generated traits. |
484 | | /// |
485 | | /// [`Store`]: wasmtime::Store |
486 | | /// |
487 | | /// # Example |
488 | | /// |
489 | | /// ``` |
490 | | /// use wasmtime_wasi::{ResourceTable, WasiCtx, WasiCtxView, WasiView, WasiCtxBuilder}; |
491 | | /// |
492 | | /// struct MyState { |
493 | | /// ctx: WasiCtx, |
494 | | /// table: ResourceTable, |
495 | | /// } |
496 | | /// |
497 | | /// impl WasiView for MyState { |
498 | | /// fn ctx(&mut self) -> WasiCtxView<'_> { |
499 | | /// WasiCtxView { ctx: &mut self.ctx, table: &mut self.table } |
500 | | /// } |
501 | | /// } |
502 | | /// |
503 | | /// impl MyState { |
504 | | /// fn new() -> MyState { |
505 | | /// let mut wasi = WasiCtxBuilder::new(); |
506 | | /// wasi.arg("./foo.wasm"); |
507 | | /// wasi.arg("--help"); |
508 | | /// wasi.env("FOO", "bar"); |
509 | | /// |
510 | | /// MyState { |
511 | | /// ctx: wasi.build(), |
512 | | /// table: ResourceTable::new(), |
513 | | /// } |
514 | | /// } |
515 | | /// } |
516 | | /// ``` |
517 | | #[derive(Default)] |
518 | | pub struct WasiCtx { |
519 | | pub(crate) cli: WasiCliCtx, |
520 | | pub(crate) clocks: WasiClocksCtx, |
521 | | pub(crate) filesystem: WasiFilesystemCtx, |
522 | | pub(crate) random: WasiRandomCtx, |
523 | | pub(crate) sockets: WasiSocketsCtx, |
524 | | } |
525 | | |
526 | | impl WasiCtx { |
527 | | /// Convenience function for calling [`WasiCtxBuilder::new`]. |
528 | 0 | pub fn builder() -> WasiCtxBuilder { |
529 | 0 | WasiCtxBuilder::new() |
530 | 0 | } |
531 | | |
532 | | /// Returns access to the underlying [`WasiRandomCtx`]. |
533 | 0 | pub fn random(&mut self) -> &mut WasiRandomCtx { |
534 | 0 | &mut self.random |
535 | 0 | } |
536 | | |
537 | | /// Returns access to the underlying [`WasiClocksCtx`]. |
538 | 0 | pub fn clocks(&mut self) -> &mut WasiClocksCtx { |
539 | 0 | &mut self.clocks |
540 | 0 | } |
541 | | |
542 | | /// Returns access to the underlying [`WasiFilesystemCtx`]. |
543 | 0 | pub fn filesystem(&mut self) -> &mut WasiFilesystemCtx { |
544 | 0 | &mut self.filesystem |
545 | 0 | } |
546 | | |
547 | | /// Returns access to the underlying [`WasiCliCtx`]. |
548 | 0 | pub fn cli(&mut self) -> &mut WasiCliCtx { |
549 | 0 | &mut self.cli |
550 | 0 | } |
551 | | |
552 | | /// Returns access to the underlying [`WasiSocketsCtx`]. |
553 | 0 | pub fn sockets(&mut self) -> &mut WasiSocketsCtx { |
554 | 0 | &mut self.sockets |
555 | 0 | } |
556 | | } |