open_dir can never create a dir
This commit is contained in:
@@ -15,12 +15,7 @@ pub trait WasiDir {
|
|||||||
caps: FileCaps,
|
caps: FileCaps,
|
||||||
) -> Result<Box<dyn WasiFile>, Error>;
|
) -> Result<Box<dyn WasiFile>, Error>;
|
||||||
|
|
||||||
fn open_dir(
|
fn open_dir(&self, symlink_follow: bool, path: &str) -> Result<Box<dyn WasiDir>, Error>;
|
||||||
&self,
|
|
||||||
symlink_follow: bool,
|
|
||||||
path: &str,
|
|
||||||
create: bool,
|
|
||||||
) -> Result<Box<dyn WasiDir>, Error>;
|
|
||||||
|
|
||||||
fn readdir(
|
fn readdir(
|
||||||
&self,
|
&self,
|
||||||
@@ -150,9 +145,10 @@ impl WasiDir for cap_std::fs::Dir {
|
|||||||
oflags: OFlags,
|
oflags: OFlags,
|
||||||
caps: FileCaps,
|
caps: FileCaps,
|
||||||
) -> Result<Box<dyn WasiFile>, Error> {
|
) -> Result<Box<dyn WasiFile>, Error> {
|
||||||
// XXX obey symlink_follow
|
use cap_fs_ext::{FollowSymlinks, OpenOptionsFollowExt};
|
||||||
// XXX how to handle fdflags like append? OFlags dont contain read|write?
|
|
||||||
let mut opts = cap_std::fs::OpenOptions::new();
|
let mut opts = cap_std::fs::OpenOptions::new();
|
||||||
|
|
||||||
if oflags.contains(&(OFlags::CREATE | OFlags::EXCLUSIVE)) {
|
if oflags.contains(&(OFlags::CREATE | OFlags::EXCLUSIVE)) {
|
||||||
opts.create_new(true);
|
opts.create_new(true);
|
||||||
} else if oflags.contains(&OFlags::CREATE) {
|
} else if oflags.contains(&OFlags::CREATE) {
|
||||||
@@ -164,23 +160,23 @@ impl WasiDir for cap_std::fs::Dir {
|
|||||||
if caps.contains(&FileCaps::READ) {
|
if caps.contains(&FileCaps::READ) {
|
||||||
opts.read(true);
|
opts.read(true);
|
||||||
}
|
}
|
||||||
if caps.contains(&FileCaps::WRITE) {
|
if caps.contains(&FileCaps::WRITE)
|
||||||
|
|| caps.contains(&FileCaps::DATASYNC)
|
||||||
|
|| caps.contains(&FileCaps::ALLOCATE)
|
||||||
|
|| caps.contains(&FileCaps::FILESTAT_SET_SIZE)
|
||||||
|
{
|
||||||
opts.write(true);
|
opts.write(true);
|
||||||
}
|
}
|
||||||
|
if symlink_follow {
|
||||||
|
opts.follow(FollowSymlinks::Yes);
|
||||||
|
}
|
||||||
|
|
||||||
debug!("Dir::open_file({:?}, {:?})", path, opts);
|
|
||||||
let f = self.open_with(Path::new(path), &opts)?;
|
let f = self.open_with(Path::new(path), &opts)?;
|
||||||
debug!("succeeded");
|
|
||||||
Ok(Box::new(f))
|
Ok(Box::new(f))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn open_dir(
|
fn open_dir(&self, symlink_follow: bool, path: &str) -> Result<Box<dyn WasiDir>, Error> {
|
||||||
&self,
|
// XXX obey symlink_follow
|
||||||
symlink_follow: bool,
|
|
||||||
path: &str,
|
|
||||||
create: bool,
|
|
||||||
) -> Result<Box<dyn WasiDir>, Error> {
|
|
||||||
// XXX obey symlink_follow, create
|
|
||||||
let d = self.open_dir(Path::new(path))?;
|
let d = self.open_dir(Path::new(path))?;
|
||||||
Ok(Box::new(d))
|
Ok(Box::new(d))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -168,6 +168,7 @@ impl<'a> wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiCtx {
|
|||||||
let mut table = self.table();
|
let mut table = self.table();
|
||||||
let fd = u32::from(fd);
|
let fd = u32::from(fd);
|
||||||
|
|
||||||
|
// Fail fast: If not present in table, Badf
|
||||||
if !table.contains_key(fd) {
|
if !table.contains_key(fd) {
|
||||||
return Err(Error::Badf);
|
return Err(Error::Badf);
|
||||||
}
|
}
|
||||||
@@ -183,7 +184,7 @@ impl<'a> wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiCtx {
|
|||||||
drop(dir_entry);
|
drop(dir_entry);
|
||||||
let _ = table.delete(fd);
|
let _ = table.delete(fd);
|
||||||
} else {
|
} else {
|
||||||
// XXX do we just table delete anyway?
|
// XXX do we just table delete other entry types anyway?
|
||||||
return Err(Error::Badf);
|
return Err(Error::Badf);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -573,16 +574,21 @@ impl<'a> wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiCtx {
|
|||||||
let mut table = self.table();
|
let mut table = self.table();
|
||||||
let dir_entry: RefMut<DirEntry> = table.get(u32::from(dirfd))?;
|
let dir_entry: RefMut<DirEntry> = table.get(u32::from(dirfd))?;
|
||||||
let dir = dir_entry.get_cap(DirCaps::OPEN)?;
|
let dir = dir_entry.get_cap(DirCaps::OPEN)?;
|
||||||
|
|
||||||
let symlink_follow = dirflags.contains(&types::Lookupflags::SYMLINK_FOLLOW);
|
let symlink_follow = dirflags.contains(&types::Lookupflags::SYMLINK_FOLLOW);
|
||||||
|
|
||||||
let oflags = OFlags::from(&oflags);
|
let oflags = OFlags::from(&oflags);
|
||||||
let fdflags = FdFlags::from(&fdflags);
|
let fdflags = FdFlags::from(&fdflags);
|
||||||
let path = path.as_str()?;
|
let path = path.as_str()?;
|
||||||
if oflags.contains(&OFlags::DIRECTORY) {
|
if oflags.contains(&OFlags::DIRECTORY) {
|
||||||
let create = oflags.contains(&OFlags::CREATE);
|
if oflags.contains(&OFlags::CREATE)
|
||||||
let child_dir = dir.open_dir(symlink_follow, path.deref(), create)?;
|
|| oflags.contains(&OFlags::EXCLUSIVE)
|
||||||
|
|| oflags.contains(&OFlags::TRUNCATE)
|
||||||
|
{
|
||||||
|
return Err(Error::Inval);
|
||||||
|
}
|
||||||
|
let child_dir = dir.open_dir(symlink_follow, path.deref())?;
|
||||||
|
|
||||||
// XXX go back and check these caps conversions - probably need to validate them
|
|
||||||
// against ???
|
|
||||||
let base_caps = DirCaps::from(&fs_rights_base);
|
let base_caps = DirCaps::from(&fs_rights_base);
|
||||||
let inheriting_caps = DirCaps::from(&fs_rights_inheriting);
|
let inheriting_caps = DirCaps::from(&fs_rights_inheriting);
|
||||||
drop(dir);
|
drop(dir);
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ impl<'a> WasiSnapshotPreview1 for WasiCtx {
|
|||||||
return Err(Error::Notsup);
|
return Err(Error::Notsup);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.remove_entry(fd)?;
|
let _ = self.remove_entry(fd)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user