Add template for Windows impl
This commit is contained in:
57
src/ctx.rs
57
src/ctx.rs
@@ -1,7 +1,7 @@
|
||||
use crate::host;
|
||||
|
||||
use crate::sys::dev_null;
|
||||
use crate::sys::fdmap::{FdEntry, FdMap};
|
||||
use crate::sys::fdentry::FdEntry;
|
||||
|
||||
use failure::{bail, format_err, Error};
|
||||
use std::collections::HashMap;
|
||||
@@ -11,7 +11,7 @@ use std::io::{stderr, stdin, stdout};
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
pub struct WasiCtxBuilder {
|
||||
fds: FdMap,
|
||||
fds: HashMap<host::__wasi_fd_t, FdEntry>,
|
||||
preopens: HashMap<PathBuf, File>,
|
||||
args: Vec<CString>,
|
||||
env: HashMap<CString, CString>,
|
||||
@@ -21,15 +21,15 @@ impl WasiCtxBuilder {
|
||||
/// Builder for a new `WasiCtx`.
|
||||
pub fn new() -> Self {
|
||||
let mut builder = Self {
|
||||
fds: FdMap::new(),
|
||||
fds: HashMap::new(),
|
||||
preopens: HashMap::new(),
|
||||
args: vec![],
|
||||
env: HashMap::new(),
|
||||
};
|
||||
|
||||
builder.fds.insert_fd_entry_at(0, FdEntry::from_file(dev_null()));
|
||||
builder.fds.insert_fd_entry_at(1, FdEntry::from_file(dev_null()));
|
||||
builder.fds.insert_fd_entry_at(2, FdEntry::from_file(dev_null()));
|
||||
builder.fds.insert(0, FdEntry::from_file(dev_null()));
|
||||
builder.fds.insert(1, FdEntry::from_file(dev_null()));
|
||||
builder.fds.insert(2, FdEntry::from_file(dev_null()));
|
||||
|
||||
builder
|
||||
}
|
||||
@@ -62,9 +62,9 @@ impl WasiCtxBuilder {
|
||||
}
|
||||
|
||||
pub fn inherit_stdio(mut self) -> Self {
|
||||
self.fds.insert_fd_entry_at(0, FdEntry::duplicate(&stdin()));
|
||||
self.fds.insert_fd_entry_at(1, FdEntry::duplicate(&stdout()));
|
||||
self.fds.insert_fd_entry_at(2, FdEntry::duplicate(&stderr()));
|
||||
self.fds.insert(0, FdEntry::duplicate(&stdin()));
|
||||
self.fds.insert(1, FdEntry::duplicate(&stdout()));
|
||||
self.fds.insert(2, FdEntry::duplicate(&stderr()));
|
||||
self
|
||||
}
|
||||
|
||||
@@ -106,15 +106,22 @@ impl WasiCtxBuilder {
|
||||
}
|
||||
|
||||
pub fn build(mut self) -> Result<WasiCtx, Error> {
|
||||
// startup code starts looking at fd 3 for preopens
|
||||
let mut preopen_fd = 3;
|
||||
for (guest_path, dir) in self.preopens {
|
||||
if !dir.metadata()?.is_dir() {
|
||||
bail!("preopened file is not a directory");
|
||||
}
|
||||
|
||||
while self.fds.contains_key(&preopen_fd) {
|
||||
preopen_fd = preopen_fd
|
||||
.checked_add(1)
|
||||
.ok_or(format_err!("not enough file handles"))?;
|
||||
}
|
||||
let mut fe = FdEntry::from_file(dir);
|
||||
fe.preopen_path = Some(guest_path);
|
||||
self.fds
|
||||
.insert_fd_entry(fe)
|
||||
.map_err(|_| format_err!("not enough file handles"))?;
|
||||
self.fds.insert(preopen_fd, fe);
|
||||
preopen_fd += 1;
|
||||
}
|
||||
|
||||
let env = self
|
||||
@@ -139,7 +146,7 @@ impl WasiCtxBuilder {
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct WasiCtx {
|
||||
pub fds: FdMap,
|
||||
pub fds: HashMap<host::__wasi_fd_t, FdEntry>,
|
||||
pub args: Vec<CString>,
|
||||
pub env: Vec<CString>,
|
||||
}
|
||||
@@ -167,13 +174,33 @@ impl WasiCtx {
|
||||
rights_base: host::__wasi_rights_t,
|
||||
rights_inheriting: host::__wasi_rights_t,
|
||||
) -> Result<&FdEntry, host::__wasi_errno_t> {
|
||||
self.fds.get_fd_entry(fd, rights_base, rights_inheriting)
|
||||
if let Some(fe) = self.fds.get(&fd) {
|
||||
// validate rights
|
||||
if !fe.rights_base & rights_base != 0 || !fe.rights_inheriting & rights_inheriting != 0
|
||||
{
|
||||
Err(host::__WASI_ENOTCAPABLE)
|
||||
} else {
|
||||
Ok(fe)
|
||||
}
|
||||
} else {
|
||||
Err(host::__WASI_EBADF)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn insert_fd_entry(
|
||||
&mut self,
|
||||
fe: FdEntry,
|
||||
) -> Result<host::__wasi_fd_t, host::__wasi_errno_t> {
|
||||
self.fds.insert_fd_entry(fe)
|
||||
// never insert where stdio handles usually are
|
||||
let mut fd = 3;
|
||||
while self.fds.contains_key(&fd) {
|
||||
if let Some(next_fd) = fd.checked_add(1) {
|
||||
fd = next_fd;
|
||||
} else {
|
||||
return Err(host::__WASI_EMFILE);
|
||||
}
|
||||
}
|
||||
self.fds.insert(fd, fe);
|
||||
Ok(fd)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user