Skip to content

Commit 6ff3a9b

Browse files
committed
Allow using virtual files for stdin/out/err
This adds the ability to use virtual files not only for the file system in WASI, but also for stdin, stdout and stderr.
1 parent f365391 commit 6ff3a9b

File tree

1 file changed

+33
-22
lines changed

1 file changed

+33
-22
lines changed

crates/wasi-common/src/ctx.rs

Lines changed: 33 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,8 @@ use crate::handle::Handle;
44
use crate::sys::osdir::OsDir;
55
use crate::sys::osother::{OsOther, OsOtherExt};
66
use crate::sys::stdio::{Stderr, StderrExt, Stdin, StdinExt, Stdout, StdoutExt};
7-
use crate::virtfs::{VirtualDir, VirtualDirEntry};
8-
use crate::wasi::types;
9-
use crate::wasi::{Errno, Result};
7+
use crate::virtfs::{FileContents, InMemoryFile, VirtualDir, VirtualDirEntry};
8+
use crate::wasi::{types, Errno, Result};
109
use std::borrow::Borrow;
1110
use std::cell::RefCell;
1211
use std::collections::HashMap;
@@ -48,6 +47,7 @@ type WasiCtxBuilderResult<T> = std::result::Result<T, WasiCtxBuilderError>;
4847
enum PendingEntry {
4948
Thunk(fn() -> io::Result<Box<dyn Handle>>),
5049
OsHandle(File),
50+
Virtual(Box<dyn FileContents>),
5151
}
5252

5353
impl std::fmt::Debug for PendingEntry {
@@ -59,6 +59,7 @@ impl std::fmt::Debug for PendingEntry {
5959
f as *const fn() -> io::Result<Box<dyn Handle>>
6060
),
6161
Self::OsHandle(f) => write!(fmt, "PendingEntry::OsHandle({:?})", f),
62+
Self::Virtual(_) => write!(fmt, "PendingEntry::Virtual(...)"),
6263
}
6364
}
6465
}
@@ -247,24 +248,42 @@ impl WasiCtxBuilder {
247248
self
248249
}
249250

250-
/// Provide a File to use as stdin
251+
/// Provide a File to use as stdin.
251252
pub fn stdin(&mut self, file: File) -> &mut Self {
252253
self.stdin = Some(PendingEntry::OsHandle(file));
253254
self
254255
}
255256

256-
/// Provide a File to use as stdout
257+
/// Provide a File to use as stdout.
257258
pub fn stdout(&mut self, file: File) -> &mut Self {
258259
self.stdout = Some(PendingEntry::OsHandle(file));
259260
self
260261
}
261262

262-
/// Provide a File to use as stderr
263+
/// Provide a File to use as stderr.
263264
pub fn stderr(&mut self, file: File) -> &mut Self {
264265
self.stderr = Some(PendingEntry::OsHandle(file));
265266
self
266267
}
267268

269+
/// Provide a virtual file to use as stdin.
270+
pub fn stdin_virt(&mut self, file: Box<dyn FileContents>) -> &mut Self {
271+
self.stdin = Some(PendingEntry::Virtual(file));
272+
self
273+
}
274+
275+
/// Provide a virtual file to use as stdout.
276+
pub fn stdout_virt(&mut self, file: Box<dyn FileContents>) -> &mut Self {
277+
self.stdout = Some(PendingEntry::Virtual(file));
278+
self
279+
}
280+
281+
/// Provide a virtual file to use as stderr.
282+
pub fn stderr_virt(&mut self, file: Box<dyn FileContents>) -> &mut Self {
283+
self.stderr = Some(PendingEntry::Virtual(file));
284+
self
285+
}
286+
268287
/// Add a preopened directory.
269288
pub fn preopened_dir<P: AsRef<Path>>(&mut self, dir: File, guest_path: P) -> &mut Self {
270289
let preopen = PendingPreopen::new(move || {
@@ -360,23 +379,15 @@ impl WasiCtxBuilder {
360379
self.stderr.take().unwrap(),
361380
] {
362381
log::debug!("WasiCtx inserting entry {:?}", pending);
363-
let fd = match pending {
364-
PendingEntry::Thunk(f) => {
365-
let handle = EntryHandle::from(f()?);
366-
let entry = Entry::new(handle);
367-
entries
368-
.insert(entry)
369-
.ok_or(WasiCtxBuilderError::TooManyFilesOpen)?
370-
}
371-
PendingEntry::OsHandle(f) => {
372-
let handle = OsOther::try_from(f)?;
373-
let handle = EntryHandle::new(handle);
374-
let entry = Entry::new(handle);
375-
entries
376-
.insert(entry)
377-
.ok_or(WasiCtxBuilderError::TooManyFilesOpen)?
378-
}
382+
let handle = match pending {
383+
PendingEntry::Thunk(f) => EntryHandle::from(f()?),
384+
PendingEntry::OsHandle(f) => EntryHandle::new(OsOther::try_from(f)?),
385+
PendingEntry::Virtual(f) => EntryHandle::new(InMemoryFile::new(f)),
379386
};
387+
let entry = Entry::new(handle);
388+
let fd = entries
389+
.insert(entry)
390+
.ok_or(WasiCtxBuilderError::TooManyFilesOpen)?;
380391
log::debug!("WasiCtx inserted at {:?}", fd);
381392
}
382393
// Then add the preopen entries.

0 commit comments

Comments
 (0)