Add template for Windows impl

This commit is contained in:
Jakub Konka
2019-05-20 11:04:51 +02:00
committed by Dan Gohman
parent 7605584691
commit c3ff3cf075
20 changed files with 575 additions and 339 deletions

View File

@@ -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)
}
}