From 07a9584a08a23b44ccb95ae60fad8e7345d05e3f Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Tue, 5 Jan 2021 12:19:56 -0800 Subject: [PATCH] add hard_link to dir --- crates/wasi-c2/TEST_FAILURES | 6 +++--- crates/wasi-c2/src/dir.rs | 21 +++++++++++++++++++++ crates/wasi-c2/src/snapshots/preview_1.rs | 18 +++++++++++++++--- 3 files changed, 39 insertions(+), 6 deletions(-) diff --git a/crates/wasi-c2/TEST_FAILURES b/crates/wasi-c2/TEST_FAILURES index 866e4a060f..1c45606b01 100644 --- a/crates/wasi-c2/TEST_FAILURES +++ b/crates/wasi-c2/TEST_FAILURES @@ -1,17 +1,17 @@ wasi_tests::dangling_symlink - - Dir::open_dir nofollow not yet implemented + - symlink following behavior not yet implemented wasi_tests::directory_seek - something weird about directory open rights / fdstat. need debug impl of Caps to see about this wasi_tests::fd_flags_set - set_fdflags is not implemented. test wanted to clear O_APPEND mode wasi_tests::nofollow_errors - - nofollow not implemented for dirs + - symlink following behavior not yet implemented wasi_tests::path_filestat - fdstat.fs_flags is not populated correctly wasi_tests::path_link - - path_link is not implemented + - symlink following behavior not yet implemented wasi_tests::path_rename_trailing_slashes - unclear, trailing slash behavior is wrong wasi_tests::path_symlink_trailing_slashes diff --git a/crates/wasi-c2/src/dir.rs b/crates/wasi-c2/src/dir.rs index d70e3c554c..0e851cd293 100644 --- a/crates/wasi-c2/src/dir.rs +++ b/crates/wasi-c2/src/dir.rs @@ -27,6 +27,13 @@ pub trait WasiDir { fn read_link(&self, path: &str) -> Result; fn get_filestat(&self) -> Result; fn rename(&self, path: &str, dest_dir: &dyn WasiDir, dest_path: &str) -> Result<(), Error>; + fn hard_link( + &self, + path: &str, + symlink_follow: bool, + target_dir: &dyn WasiDir, + target_path: &str, + ) -> Result<(), Error>; } pub(crate) struct DirEntry { @@ -363,4 +370,18 @@ impl WasiDir for cap_std::fs::Dir { self.rename(Path::new(src_path), dest_dir, Path::new(dest_path))?; Ok(()) } + fn hard_link( + &self, + src_path: &str, + symlink_follow: bool, + target_dir: &dyn WasiDir, + target_path: &str, + ) -> Result<(), Error> { + let target_dir = target_dir + .as_any() + .downcast_ref::() + .ok_or(Error::NotCapable)?; + self.hard_link(Path::new(src_path), target_dir, Path::new(target_path))?; + Ok(()) + } } diff --git a/crates/wasi-c2/src/snapshots/preview_1.rs b/crates/wasi-c2/src/snapshots/preview_1.rs index 9bec5adb6c..04deb9f80b 100644 --- a/crates/wasi-c2/src/snapshots/preview_1.rs +++ b/crates/wasi-c2/src/snapshots/preview_1.rs @@ -670,10 +670,22 @@ impl<'a> wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiCtx { src_fd: types::Fd, src_flags: types::Lookupflags, src_path: &GuestPtr<'_, str>, - dest_fd: types::Fd, - dest_path: &GuestPtr<'_, str>, + target_fd: types::Fd, + target_path: &GuestPtr<'_, str>, ) -> Result<(), Error> { - unimplemented!() + let table = self.table(); + let src_entry: Ref = table.get(u32::from(src_fd))?; + let src_dir = src_entry.get_cap(DirCaps::LINK_SOURCE)?; + let target_entry: Ref = table.get(u32::from(target_fd))?; + let target_dir = target_entry.get_cap(DirCaps::LINK_TARGET)?; + let symlink_follow = src_flags.contains(&types::Lookupflags::SYMLINK_FOLLOW); + + src_dir.hard_link( + src_path.as_str()?.deref(), + symlink_follow, + target_dir.deref(), + target_path.as_str()?.deref(), + ) } fn path_open(