this is indeed a nice way to do refs!

This commit is contained in:
Pat Hickey
2021-01-13 15:11:11 -08:00
parent 7beb52a2bc
commit ea94d6f79d
3 changed files with 169 additions and 128 deletions

View File

@@ -3,6 +3,7 @@ use crate::file::{FdFlags, FileCaps, FileType, Filestat, OFlags, WasiFile};
use bitflags::bitflags;
use cap_fs_ext::SystemTimeSpec;
use std::any::Any;
use std::cell::Ref;
use std::convert::TryInto;
use std::ops::Deref;
use std::path::{Path, PathBuf};
@@ -66,9 +67,9 @@ impl DirEntry {
dir,
}
}
pub fn get_cap(&self, caps: DirCaps) -> Result<&dyn WasiDir, Error> {
pub fn capable_of_dir(&self, caps: DirCaps) -> Result<(), Error> {
if self.caps.contains(caps) {
Ok(self.dir.deref())
Ok(())
} else {
Err(Error::DirNotCapable {
desired: caps,
@@ -76,15 +77,23 @@ impl DirEntry {
})
}
}
pub fn drop_caps_to(&mut self, caps: DirCaps, file_caps: FileCaps) -> Result<(), Error> {
if self.caps.contains(caps) && self.file_caps.contains(file_caps) {
self.caps = caps;
self.file_caps = file_caps;
pub fn capable_of_file(&self, caps: FileCaps) -> Result<(), Error> {
if self.file_caps.contains(caps) {
Ok(())
} else {
Err(Error::NotCapable)
Err(Error::FileNotCapable {
desired: caps,
has: self.file_caps,
})
}
}
pub fn drop_caps_to(&mut self, caps: DirCaps, file_caps: FileCaps) -> Result<(), Error> {
self.capable_of_dir(caps)?;
self.capable_of_file(file_caps)?;
self.caps = caps;
self.file_caps = file_caps;
Ok(())
}
pub fn child_dir_caps(&self, desired_caps: DirCaps) -> DirCaps {
self.caps & desired_caps
}
@@ -102,6 +111,17 @@ impl DirEntry {
}
}
pub trait DirEntryExt<'a> {
fn get_cap(self, caps: DirCaps) -> Result<Ref<'a, dyn WasiDir>, Error>;
}
impl<'a> DirEntryExt<'a> for Ref<'a, DirEntry> {
fn get_cap(self, caps: DirCaps) -> Result<Ref<'a, dyn WasiDir>, Error> {
self.capable_of_dir(caps)?;
Ok(Ref::map(self, |r| r.dir.deref()))
}
}
bitflags! {
pub struct DirCaps: u32 {
const CREATE_DIRECTORY = 0b1;
@@ -129,11 +149,15 @@ pub struct DirFdStat {
pub dir_caps: DirCaps,
}
pub trait TableDirExt {
pub(crate) trait TableDirExt {
fn get_dir(&self, fd: u32) -> Result<Ref<DirEntry>, Error>;
fn is_preopen(&self, fd: u32) -> bool;
}
impl TableDirExt for crate::table::Table {
fn get_dir(&self, fd: u32) -> Result<Ref<DirEntry>, Error> {
self.get(fd)
}
fn is_preopen(&self, fd: u32) -> bool {
if self.is::<DirEntry>(fd) {
let dir_entry: std::cell::Ref<DirEntry> = self.get(fd).unwrap();