add directory rename

This commit is contained in:
Pat Hickey
2021-01-05 12:14:07 -08:00
parent 94d2280187
commit 21cd55b0a7
3 changed files with 29 additions and 11 deletions

View File

@@ -12,11 +12,8 @@ wasi_tests::path_filestat
- fdstat.fs_flags is not populated correctly - fdstat.fs_flags is not populated correctly
wasi_tests::path_link wasi_tests::path_link
- path_link is not implemented - path_link is not implemented
wasi_tests::path_rename
- path_rename is not implemented. we need to be able to downcast a dyn
WasiDir to a concrete Dir for this to be possible - need to reintroduce Any to hierarchy
wasi_tests::path_rename_trailing_slashes wasi_tests::path_rename_trailing_slashes
- path_rename is not implemented - unclear, trailing slash behavior is wrong
wasi_tests::path_symlink_trailing_slashes wasi_tests::path_symlink_trailing_slashes
- unclear, path_symlink is giving a ENOTDIR when it expects an EEXIST... - unclear, path_symlink is giving a ENOTDIR when it expects an EEXIST...
wasi_tests::poll_oneoff wasi_tests::poll_oneoff

View File

@@ -1,10 +1,12 @@
use crate::error::Error; use crate::error::Error;
use crate::file::{FdFlags, FileCaps, FileType, Filestat, OFlags, WasiFile}; use crate::file::{FdFlags, FileCaps, FileType, Filestat, OFlags, WasiFile};
use std::any::Any;
use std::convert::TryInto; use std::convert::TryInto;
use std::ops::Deref; use std::ops::Deref;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
pub trait WasiDir { pub trait WasiDir {
fn as_any(&self) -> &dyn Any;
fn open_file( fn open_file(
&self, &self,
symlink_follow: bool, symlink_follow: bool,
@@ -24,6 +26,7 @@ pub trait WasiDir {
fn unlink_file(&self, path: &str) -> Result<(), Error>; fn unlink_file(&self, path: &str) -> Result<(), Error>;
fn read_link(&self, path: &str) -> Result<PathBuf, Error>; fn read_link(&self, path: &str) -> Result<PathBuf, Error>;
fn get_filestat(&self) -> Result<Filestat, Error>; fn get_filestat(&self) -> Result<Filestat, Error>;
fn rename(&self, path: &str, dest_dir: &dyn WasiDir, dest_path: &str) -> Result<(), Error>;
} }
pub(crate) struct DirEntry { pub(crate) struct DirEntry {
@@ -196,6 +199,9 @@ impl From<ReaddirCursor> for u64 {
} }
impl WasiDir for cap_std::fs::Dir { impl WasiDir for cap_std::fs::Dir {
fn as_any(&self) -> &dyn Any {
self
}
fn open_file( fn open_file(
&self, &self,
symlink_follow: bool, symlink_follow: bool,
@@ -349,4 +355,12 @@ impl WasiDir for cap_std::fs::Dir {
ctim: meta.created().map(|t| Some(t.into_std())).unwrap_or(None), ctim: meta.created().map(|t| Some(t.into_std())).unwrap_or(None),
}) })
} }
fn rename(&self, src_path: &str, dest_dir: &dyn WasiDir, dest_path: &str) -> Result<(), Error> {
let dest_dir = dest_dir
.as_any()
.downcast_ref::<Self>()
.ok_or(Error::NotCapable)?;
self.rename(Path::new(src_path), dest_dir, Path::new(dest_path))?;
Ok(())
}
} }

View File

@@ -771,14 +771,21 @@ impl<'a> wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiCtx {
fn path_rename( fn path_rename(
&self, &self,
old_fd: types::Fd, src_fd: types::Fd,
old_path: &GuestPtr<'_, str>, src_path: &GuestPtr<'_, str>,
new_fd: types::Fd, dest_fd: types::Fd,
new_path: &GuestPtr<'_, str>, dest_path: &GuestPtr<'_, str>,
) -> Result<(), Error> { ) -> Result<(), Error> {
// XXX: Dir::rename requires (to_dir: &Self), but in the table we just have a dyn WasiDir. let table = self.table();
// The downcast isn't possible. let src_entry: Ref<DirEntry> = table.get(u32::from(src_fd))?;
unimplemented!() let src_dir = src_entry.get_cap(DirCaps::RENAME_SOURCE)?;
let dest_entry: Ref<DirEntry> = table.get(u32::from(dest_fd))?;
let dest_dir = dest_entry.get_cap(DirCaps::RENAME_TARGET)?;
src_dir.rename(
src_path.as_str()?.deref(),
dest_dir.deref(),
dest_path.as_str()?.deref(),
)
} }
fn path_symlink( fn path_symlink(