preopens with Caps::all, implement create, remove dir, remove file

This commit is contained in:
Pat Hickey
2020-12-16 15:15:48 -08:00
parent c0461ca170
commit 27ddbda829
5 changed files with 80 additions and 20 deletions

View File

@@ -100,7 +100,7 @@ impl WasiCtxBuilder {
dir: Box<dyn WasiDir>, dir: Box<dyn WasiDir>,
path: impl AsRef<Path>, path: impl AsRef<Path>,
) -> Result<&mut Self, Error> { ) -> Result<&mut Self, Error> {
let caps = DirCaps::OPEN | DirCaps::CREATE_FILE; // XXX more base caps let caps = DirCaps::all();
let file_caps = FileCaps::READ | FileCaps::WRITE; // XXX more base caps let file_caps = FileCaps::READ | FileCaps::WRITE; // XXX more base caps
self.0.table().push(Box::new(DirEntry::new( self.0.table().push(Box::new(DirEntry::new(
caps, caps,

View File

@@ -16,10 +16,16 @@ pub trait WasiDir {
fn open_dir(&self, symlink_follow: bool, path: &str) -> Result<Box<dyn WasiDir>, Error>; fn open_dir(&self, symlink_follow: bool, path: &str) -> Result<Box<dyn WasiDir>, Error>;
fn create_dir(&self, path: &str) -> Result<(), Error>;
fn readdir( fn readdir(
&self, &self,
cursor: ReaddirCursor, cursor: ReaddirCursor,
) -> Result<Box<dyn Iterator<Item = Result<(ReaddirEntity, String), Error>>>, Error>; ) -> Result<Box<dyn Iterator<Item = Result<(ReaddirEntity, String), Error>>>, Error>;
fn remove_dir(&self, path: &str) -> Result<(), Error>;
fn unlink_file(&self, path: &str) -> Result<(), Error>;
} }
pub(crate) struct DirEntry { pub(crate) struct DirEntry {
@@ -112,6 +118,31 @@ impl DirCaps {
pub const SYMLINK: Self = DirCaps { flags: 512 }; pub const SYMLINK: Self = DirCaps { flags: 512 };
pub const REMOVE_DIRECTORY: Self = DirCaps { flags: 1024 }; pub const REMOVE_DIRECTORY: Self = DirCaps { flags: 1024 };
pub const UNLINK_FILE: Self = DirCaps { flags: 2048 }; pub const UNLINK_FILE: Self = DirCaps { flags: 2048 };
// Missing that are in wasi-common directory_base:
// FD_FDSTAT_SET_FLAGS
// FD_SYNC
// FD_ADVISE
// PATH_FILESTAT_GET
// PATH_FILESTAT_SET_SIZE
// PATH_FILESTAT_SET_TIMES
// FD_FILESTAT_GET
// FD_FILESTAT_SET_TIMES
pub fn all() -> DirCaps {
Self::CREATE_DIRECTORY
| Self::CREATE_FILE
| Self::LINK_SOURCE
| Self::LINK_TARGET
| Self::OPEN
| Self::READDIR
| Self::READLINK
| Self::RENAME_SOURCE
| Self::RENAME_TARGET
| Self::SYMLINK
| Self::REMOVE_DIRECTORY
| Self::UNLINK_FILE
}
} }
impl std::ops::BitOr for DirCaps { impl std::ops::BitOr for DirCaps {
@@ -128,12 +159,6 @@ pub struct DirStat {
pub dir_caps: DirCaps, pub dir_caps: DirCaps,
} }
impl std::fmt::Display for DirCaps {
fn fmt(&self, _f: &mut std::fmt::Formatter) -> std::fmt::Result {
todo!()
}
}
pub trait TableDirExt { pub trait TableDirExt {
fn is_preopen(&self, fd: u32) -> bool; fn is_preopen(&self, fd: u32) -> bool;
} }
@@ -219,6 +244,10 @@ impl WasiDir for cap_std::fs::Dir {
Ok(Box::new(d)) Ok(Box::new(d))
} }
fn create_dir(&self, path: &str) -> Result<(), Error> {
self.create_dir(Path::new(path))?;
Ok(())
}
fn readdir( fn readdir(
&self, &self,
cursor: ReaddirCursor, cursor: ReaddirCursor,
@@ -257,4 +286,14 @@ impl WasiDir for cap_std::fs::Dir {
Ok((entity, name)) Ok((entity, name))
}))) })))
} }
fn remove_dir(&self, path: &str) -> Result<(), Error> {
self.remove_dir(Path::new(path))?;
Ok(())
}
fn unlink_file(&self, path: &str) -> Result<(), Error> {
self.remove_file(Path::new(path))?;
Ok(())
}
} }

View File

@@ -17,11 +17,11 @@ pub enum Error {
GetRandom(#[from] getrandom::Error), GetRandom(#[from] getrandom::Error),
/// Errno::Notcapable: Extension: Capabilities insufficient /// Errno::Notcapable: Extension: Capabilities insufficient
#[error("File not capable: desired {desired}, has {has}")] #[error("File not capable: desired {desired:?}, has {has:?}")]
FileNotCapable { desired: FileCaps, has: FileCaps }, FileNotCapable { desired: FileCaps, has: FileCaps },
/// Errno::Notcapable: Extension: Capabilities insufficient /// Errno::Notcapable: Extension: Capabilities insufficient
#[error("Directory not capable: desired {desired}, has {has}")] #[error("Directory not capable: desired {desired:?}, has {has:?}")]
DirNotCapable { desired: DirCaps, has: DirCaps }, DirNotCapable { desired: DirCaps, has: DirCaps },
/// Idk what the deal with this guy is yet /// Idk what the deal with this guy is yet

View File

@@ -170,6 +170,21 @@ impl FileCaps {
pub const FILESTAT_GET: Self = FileCaps { flags: 512 }; pub const FILESTAT_GET: Self = FileCaps { flags: 512 };
pub const FILESTAT_SET_SIZE: Self = FileCaps { flags: 1024 }; pub const FILESTAT_SET_SIZE: Self = FileCaps { flags: 1024 };
pub const FILESTAT_SET_TIMES: Self = FileCaps { flags: 2048 }; pub const FILESTAT_SET_TIMES: Self = FileCaps { flags: 2048 };
pub fn all() -> FileCaps {
Self::DATASYNC
| Self::READ
| Self::SEEK
| Self::FDSTAT_SET_FLAGS
| Self::SYNC
| Self::TELL
| Self::WRITE
| Self::ADVISE
| Self::ALLOCATE
| Self::FILESTAT_GET
| Self::FILESTAT_SET_SIZE
| Self::FILESTAT_SET_TIMES
}
} }
impl std::ops::BitOr for FileCaps { impl std::ops::BitOr for FileCaps {
@@ -181,12 +196,6 @@ impl std::ops::BitOr for FileCaps {
} }
} }
impl std::fmt::Display for FileCaps {
fn fmt(&self, _f: &mut std::fmt::Formatter) -> std::fmt::Result {
todo!()
}
}
pub struct FdStat { pub struct FdStat {
pub filetype: Filetype, pub filetype: Filetype,
pub caps: FileCaps, pub caps: FileCaps,

View File

@@ -92,8 +92,8 @@ impl From<wiggle::GuestError> for types::Errno {
PtrBorrowed { .. } => Self::Fault, PtrBorrowed { .. } => Self::Fault,
InvalidUtf8 { .. } => Self::Ilseq, InvalidUtf8 { .. } => Self::Ilseq,
TryFromIntError { .. } => Self::Overflow, TryFromIntError { .. } => Self::Overflow,
InFunc { .. } => Self::Inval, InFunc { err, .. } => types::Errno::from(*err),
InDataField { .. } => Self::Inval, InDataField { err, .. } => types::Errno::from(*err),
SliceLengthsDiffer { .. } => Self::Fault, SliceLengthsDiffer { .. } => Self::Fault,
BorrowCheckerOutOfHandles { .. } => Self::Fault, BorrowCheckerOutOfHandles { .. } => Self::Fault,
} }
@@ -527,7 +527,11 @@ impl<'a> wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiCtx {
dirfd: types::Fd, dirfd: types::Fd,
path: &GuestPtr<'_, str>, path: &GuestPtr<'_, str>,
) -> Result<(), Error> { ) -> Result<(), Error> {
unimplemented!() let table = self.table();
let dir_entry: RefMut<DirEntry> = table.get(u32::from(dirfd))?;
let dir = dir_entry.get_cap(DirCaps::CREATE_DIRECTORY)?;
let path = path.as_str()?;
dir.create_dir(path.deref())
} }
fn path_filestat_get( fn path_filestat_get(
@@ -628,7 +632,11 @@ impl<'a> wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiCtx {
dirfd: types::Fd, dirfd: types::Fd,
path: &GuestPtr<'_, str>, path: &GuestPtr<'_, str>,
) -> Result<(), Error> { ) -> Result<(), Error> {
unimplemented!() let table = self.table();
let dir_entry: RefMut<DirEntry> = table.get(u32::from(dirfd))?;
let dir = dir_entry.get_cap(DirCaps::REMOVE_DIRECTORY)?;
let path = path.as_str()?;
dir.remove_dir(path.deref())
} }
fn path_rename( fn path_rename(
@@ -651,7 +659,11 @@ impl<'a> wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiCtx {
} }
fn path_unlink_file(&self, dirfd: types::Fd, path: &GuestPtr<'_, str>) -> Result<(), Error> { fn path_unlink_file(&self, dirfd: types::Fd, path: &GuestPtr<'_, str>) -> Result<(), Error> {
unimplemented!() let table = self.table();
let dir_entry: RefMut<DirEntry> = table.get(u32::from(dirfd))?;
let dir = dir_entry.get_cap(DirCaps::UNLINK_FILE)?;
let path = path.as_str()?;
dir.unlink_file(path.deref())
} }
fn poll_oneoff( fn poll_oneoff(