add directory rename
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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(
|
||||||
|
|||||||
Reference in New Issue
Block a user