From ce13cd9e7712daff3927f0321d39f3f65ecfd064 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Tue, 5 Jan 2021 14:24:02 -0800 Subject: [PATCH] dir: add set times --- crates/wasi-c2/Cargo.toml | 2 +- crates/wasi-c2/src/dir.rs | 16 ++++++ crates/wasi-c2/src/snapshots/preview_1.rs | 70 +++++++++++++++-------- 3 files changed, 63 insertions(+), 25 deletions(-) diff --git a/crates/wasi-c2/Cargo.toml b/crates/wasi-c2/Cargo.toml index e808da345c..15b110118a 100644 --- a/crates/wasi-c2/Cargo.toml +++ b/crates/wasi-c2/Cargo.toml @@ -29,7 +29,7 @@ cap-std = "0.8" cap-fs-ext = "0.8" cap-time-ext = "0.8" cap-rand = "0.8" -fs-set-times = "0.2.1" +fs-set-times = "0.2.2" cfg-if = "1" [badges] diff --git a/crates/wasi-c2/src/dir.rs b/crates/wasi-c2/src/dir.rs index 1d4886d36f..81c6ea3af7 100644 --- a/crates/wasi-c2/src/dir.rs +++ b/crates/wasi-c2/src/dir.rs @@ -1,5 +1,6 @@ use crate::error::Error; use crate::file::{FdFlags, FileCaps, FileType, Filestat, OFlags, WasiFile}; +use cap_fs_ext::SystemTimeSpec; use std::any::Any; use std::convert::TryInto; use std::ops::Deref; @@ -35,6 +36,12 @@ pub trait WasiDir { target_dir: &dyn WasiDir, target_path: &str, ) -> Result<(), Error>; + fn set_times( + &self, + path: &str, + atime: Option, + mtime: Option, + ) -> Result<(), Error>; } pub(crate) struct DirEntry { @@ -399,4 +406,13 @@ impl WasiDir for cap_std::fs::Dir { self.hard_link(Path::new(src_path), target_dir, Path::new(target_path))?; Ok(()) } + fn set_times( + &self, + path: &str, + atime: Option, + mtime: Option, + ) -> Result<(), Error> { + cap_fs_ext::DirExt::set_times(self, Path::new(path), atime, mtime)?; + Ok(()) + } } diff --git a/crates/wasi-c2/src/snapshots/preview_1.rs b/crates/wasi-c2/src/snapshots/preview_1.rs index 98e149fe8e..c6f568c4d4 100644 --- a/crates/wasi-c2/src/snapshots/preview_1.rs +++ b/crates/wasi-c2/src/snapshots/preview_1.rs @@ -322,8 +322,9 @@ impl<'a> wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiCtx { mtim: types::Timestamp, fst_flags: types::Fstflags, ) -> Result<(), Error> { - use std::time::{Duration, UNIX_EPOCH}; - // Validate flags, transform into well-structured arguments + let fd = u32::from(fd); + let table = self.table(); + // Validate flags let set_atim = fst_flags.contains(&types::Fstflags::ATIM); let set_atim_now = fst_flags.contains(&types::Fstflags::ATIM_NOW); let set_mtim = fst_flags.contains(&types::Fstflags::MTIM); @@ -331,36 +332,57 @@ impl<'a> wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiCtx { if (set_atim && set_atim_now) || (set_mtim && set_mtim_now) { return Err(Error::Inval); } - let atim = if set_atim { - Some(SystemTimeSpec::Absolute( - UNIX_EPOCH + Duration::from_nanos(atim), - )) - } else if set_atim_now { - Some(SystemTimeSpec::SymbolicNow) - } else { - None - }; - let mtim = if set_mtim { - Some(SystemTimeSpec::Absolute( - UNIX_EPOCH + Duration::from_nanos(mtim), - )) - } else if set_mtim_now { - Some(SystemTimeSpec::SymbolicNow) - } else { - None - }; - - let fd = u32::from(fd); - let table = self.table(); if table.is::(fd) { + use std::time::{Duration, UNIX_EPOCH}; + let atim = if set_atim { + Some(SystemTimeSpec::Absolute( + UNIX_EPOCH + Duration::from_nanos(atim), + )) + } else if set_atim_now { + Some(SystemTimeSpec::SymbolicNow) + } else { + None + }; + let mtim = if set_mtim { + Some(SystemTimeSpec::Absolute( + UNIX_EPOCH + Duration::from_nanos(mtim), + )) + } else if set_mtim_now { + Some(SystemTimeSpec::SymbolicNow) + } else { + None + }; + let file_entry: Ref = table.get(fd).unwrap(); let f = file_entry.get_cap(FileCaps::FILESTAT_SET_TIMES)?; f.set_times(atim, mtim)?; Ok(()) } else if table.is::(fd) { + use cap_std::time::{Duration, SystemClock}; let dir_entry: Ref = table.get(fd).unwrap(); let d = dir_entry.get_cap(DirCaps::FILESTAT_SET_TIMES)?; - todo!("d.set_times(atim, mtim)?;") + + use cap_fs_ext::SystemTimeSpec; + let atim = if set_atim { + Some(SystemTimeSpec::Absolute( + SystemClock::UNIX_EPOCH + Duration::from_nanos(atim), + )) + } else if set_atim_now { + Some(SystemTimeSpec::SymbolicNow) + } else { + None + }; + let mtim = if set_mtim { + Some(SystemTimeSpec::Absolute( + SystemClock::UNIX_EPOCH + Duration::from_nanos(mtim), + )) + } else if set_mtim_now { + Some(SystemTimeSpec::SymbolicNow) + } else { + None + }; + + d.set_times(".", atim, mtim) } else { Err(Error::Badf) }