implement some of fd_prestat_get

This commit is contained in:
Mark McCaskey 2019-04-02 10:58:22 -07:00
parent 435629300b
commit d421e91407
4 changed files with 61 additions and 8 deletions

View File

@ -15,7 +15,7 @@ use std::ffi::c_void;
pub use self::utils::is_wasi_module;
use wasmer_runtime_core::{debug, func, import::ImportObject, imports};
use wasmer_runtime_core::{func, import::ImportObject, imports};
pub fn generate_import_object(args: Vec<Vec<u8>>, envs: Vec<Vec<u8>>) -> ImportObject {
let state_gen = move || {

View File

@ -194,6 +194,21 @@ impl WasiFs {
fs_rights_inheriting: fd.rights, // TODO(lachlan): Is this right?
})
}
pub fn prestat_fd(&self, fd: __wasi_fd_t) -> Result<__wasi_prestat_t, __wasi_errno_t> {
let fd = self.fd_map.get(&fd).ok_or(__WASI_EBADF)?;
let inode_val = &self.inodes[fd.inode];
if inode_val.is_preopened {
Ok(PrestatEnum::PreOpenDir {
pr_name_len: inode_val.name.len() as u32,
}
.get_untagged())
} else {
Err(__WASI_EBADF)
}
}
}
pub struct WasiState<'a> {

View File

@ -380,6 +380,14 @@ pub fn fd_pread(
}
}
/// ### `fd_prestat_get()`
/// Get metadata about a preopened file descriptor
/// Input:
/// - `__wasi_fd_t fd`
/// The preopened file descriptor to query
/// Output:
/// - `__wasi_prestat *buf`
/// Where the metadata will be written
pub fn fd_prestat_get(
ctx: &mut Ctx,
fd: __wasi_fd_t,
@ -388,13 +396,12 @@ pub fn fd_prestat_get(
debug!("wasi::fd_prestat_get: fd={}", fd);
let memory = ctx.memory(0);
if let Ok(prestat_ptr) = buf.deref(memory) {
// open fd
// write info to prestat_ptr
__WASI_ESUCCESS
} else {
__WASI_EFAULT
}
let prestat_ptr = wasi_try!(buf.deref(memory));
let state = get_wasi_state(ctx);
prestat_ptr.set(wasi_try!(state.fs.prestat_fd(fd)));
__WASI_ESUCCESS
}
pub fn fd_prestat_dir_name(

View File

@ -191,6 +191,37 @@ pub struct __wasi_prestat_t {
u: __wasi_prestat_u,
}
#[derive(Copy, Clone)]
pub enum PrestatEnum {
PreOpenDir { pr_name_len: u32 },
}
impl __wasi_prestat_t {
pub fn get_tagged(&self) -> PrestatEnum {
match self.pr_type {
__WASI_PREOPENTYPE_DIR => PrestatEnum::PreOpenDir {
pr_name_len: unsafe { self.u.dir.pr_name_len },
},
_ => panic!("Invalid enum variant in __wasi_prestat_t: {}", self.pr_type),
}
}
}
impl PrestatEnum {
pub fn get_untagged(&self) -> __wasi_prestat_t {
match self {
PrestatEnum::PreOpenDir { pr_name_len } => __wasi_prestat_t {
pr_type: __WASI_PREOPENTYPE_DIR,
u: __wasi_prestat_u {
dir: __wasi_prestat_u_dir_t {
pr_name_len: *pr_name_len,
},
},
},
}
}
}
unsafe impl ValueType for __wasi_prestat_t {}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]