preopens with Caps::all, implement create, remove dir, remove file
This commit is contained in:
@@ -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,
|
||||||
|
|||||||
@@ -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(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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(
|
||||||
|
|||||||
Reference in New Issue
Block a user