diff --git a/crates/wasi-c2/cap-std-sync/src/dir.rs b/crates/wasi-c2/cap-std-sync/src/dir.rs index ca75dfbf53..d672940ea5 100644 --- a/crates/wasi-c2/cap-std-sync/src/dir.rs +++ b/crates/wasi-c2/cap-std-sync/src/dir.rs @@ -175,8 +175,12 @@ impl WasiDir for Dir { ctim: meta.created().map(|t| Some(t.into_std())).unwrap_or(None), }) } - fn get_path_filestat(&self, path: &str) -> Result { - let meta = self.0.metadata(Path::new(path))?; + fn get_path_filestat(&self, path: &str, follow_symlinks: bool) -> Result { + let meta = if follow_symlinks { + self.0.metadata(Path::new(path))? + } else { + self.0.symlink_metadata(Path::new(path))? + }; Ok(Filestat { device_id: meta.dev(), inode: meta.ino(), @@ -217,12 +221,21 @@ impl WasiDir for Dir { path: &str, atime: Option, mtime: Option, + follow_symlinks: bool, ) -> Result<(), Error> { - self.0.set_times( - Path::new(path), - convert_systimespec(atime), - convert_systimespec(mtime), - )?; + if follow_symlinks { + self.0.set_times( + Path::new(path), + convert_systimespec(atime), + convert_systimespec(mtime), + )?; + } else { + self.0.set_symlink_times( + Path::new(path), + convert_systimespec(atime), + convert_systimespec(mtime), + )?; + } Ok(()) } } diff --git a/crates/wasi-c2/src/dir.rs b/crates/wasi-c2/src/dir.rs index 3d2ffa1aa6..2f3ab442ff 100644 --- a/crates/wasi-c2/src/dir.rs +++ b/crates/wasi-c2/src/dir.rs @@ -27,7 +27,7 @@ pub trait WasiDir { fn unlink_file(&self, path: &str) -> Result<(), Error>; fn read_link(&self, path: &str) -> Result; fn get_filestat(&self) -> Result; - fn get_path_filestat(&self, path: &str) -> Result; + fn get_path_filestat(&self, path: &str, follow_symlinks: bool) -> Result; fn rename(&self, path: &str, dest_dir: &dyn WasiDir, dest_path: &str) -> Result<(), Error>; fn hard_link( &self, @@ -40,6 +40,7 @@ pub trait WasiDir { path: &str, atime: Option, mtime: Option, + follow_symlinks: bool, ) -> Result<(), Error>; } diff --git a/crates/wasi-c2/src/snapshots/preview_1.rs b/crates/wasi-c2/src/snapshots/preview_1.rs index d948d51321..f04b2ae6f5 100644 --- a/crates/wasi-c2/src/snapshots/preview_1.rs +++ b/crates/wasi-c2/src/snapshots/preview_1.rs @@ -1,4 +1,3 @@ -#![allow(unused_variables)] use crate::{ dir::{DirCaps, DirEntry, DirEntryExt, DirFdStat, ReaddirCursor, ReaddirEntity, TableDirExt}, file::{ @@ -417,7 +416,7 @@ impl<'a> wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiCtx { .get_dir(fd) .expect("checked that entry is dir") .get_cap(DirCaps::FILESTAT_SET_TIMES)? - .set_times(".", atim, mtim) + .set_times(".", atim, mtim, false) } else { Err(Error::badf()) } @@ -703,7 +702,10 @@ impl<'a> wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiCtx { .table() .get_dir(u32::from(dirfd))? .get_cap(DirCaps::PATH_FILESTAT_GET)? - .get_path_filestat(path.as_str()?.deref())?; + .get_path_filestat( + path.as_str()?.deref(), + flags.contains(types::Lookupflags::SYMLINK_FOLLOW), + )?; Ok(types::Filestat::from(filestat)) } @@ -726,7 +728,12 @@ impl<'a> wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiCtx { self.table() .get_dir(u32::from(dirfd))? .get_cap(DirCaps::PATH_FILESTAT_SET_TIMES)? - .set_times(path.as_str()?.deref(), atim, mtim) + .set_times( + path.as_str()?.deref(), + atim, + mtim, + flags.contains(types::Lookupflags::SYMLINK_FOLLOW), + ) } fn path_link(