From 61d72a179b1a280b8c8a0738db10c22c9ee63fe2 Mon Sep 17 00:00:00 2001 From: Mark McCaskey Date: Thu, 1 Aug 2019 14:06:28 +0900 Subject: [PATCH] implement updating times in wasi::fd_filestat_set_times --- lib/wasi/src/state.rs | 35 +++++++++++++++++++++++++++++++---- lib/wasi/src/syscalls/mod.rs | 32 ++++++++++++++++++++++++++++++-- 2 files changed, 61 insertions(+), 6 deletions(-) diff --git a/lib/wasi/src/state.rs b/lib/wasi/src/state.rs index 8ceb10cc3..5d33aea38 100644 --- a/lib/wasi/src/state.rs +++ b/lib/wasi/src/state.rs @@ -70,18 +70,33 @@ impl WasiFsError { /// This trait relies on your file closing when it goes out of scope via `Drop` pub trait WasiFile: std::fmt::Debug + Write + Read + Seek { /// the last time the file was accessed in nanoseconds as a UNIX timestamp - fn last_accessed(&self) -> u64; + fn last_accessed(&self) -> __wasi_timestamp_t; /// the last time the file was modified in nanoseconds as a UNIX timestamp - fn last_modified(&self) -> u64; + fn last_modified(&self) -> __wasi_timestamp_t; /// the time at which the file was created in nanoseconds as a UNIX timestamp - fn created_time(&self) -> u64; + fn created_time(&self) -> __wasi_timestamp_t; + /// set the last time the file was accessed in nanoseconds as a UNIX timestamp + // TODO: stablize this in 0.7.0 by removing default impl + fn set_last_accessed(&self, _last_accessed: __wasi_timestamp_t) { + panic!("Default implementation for compatibilty in the 0.6.X releases; this will be removed in 0.7.0. Please implement WasiFile::set_last_accessed for your type before then"); + } + /// set the last time the file was modified in nanoseconds as a UNIX timestamp + // TODO: stablize this in 0.7.0 by removing default impl + fn set_last_modified(&self, _last_modified: __wasi_timestamp_t) { + panic!("Default implementation for compatibilty in the 0.6.X releases; this will be removed in 0.7.0. Please implement WasiFile::set_last_modified for your type before then"); + } + /// set the time at which the file was created in nanoseconds as a UNIX timestamp + // TODO: stablize this in 0.7.0 by removing default impl + fn set_created_time(&self, _created_time: __wasi_timestamp_t) { + panic!("Default implementation for compatibilty in the 0.6.X releases; this will be removed in 0.7.0. Please implement WasiFile::set_created_time for your type before then"); + } /// the size of the file in bytes fn size(&self) -> u64; /// Change the size of the file, if the `new_size` is greater than the current size /// the extra bytes will be allocated and zeroed // TODO: stablize this in 0.7.0 by removing default impl fn set_len(&mut self, _new_size: __wasi_filesize_t) -> Option<()> { - panic!("Default implementation for compatibilty in the 0.6.X releases; this will be removed in 0.7.X. Please implement WasiFile::allocate for your type before then"); + panic!("Default implementation for compatibilty in the 0.6.X releases; this will be removed in 0.7.0. Please implement WasiFile::allocate for your type before then"); } } @@ -96,6 +111,10 @@ impl WasiFile for fs::File { .unwrap_or(0) } + fn set_last_accessed(&self, _last_accessed: __wasi_timestamp_t) { + // TODO: figure out how to do this + } + fn last_modified(&self) -> u64 { self.metadata() .unwrap() @@ -106,6 +125,10 @@ impl WasiFile for fs::File { .unwrap_or(0) } + fn set_last_modified(&self, _last_modified: __wasi_timestamp_t) { + // TODO: figure out how to do this + } + fn created_time(&self) -> u64 { self.metadata() .unwrap() @@ -116,6 +139,10 @@ impl WasiFile for fs::File { .unwrap_or(0) } + fn set_created_time(&self, _created_time: __wasi_timestamp_t) { + // TODO: figure out how to do this + } + fn size(&self) -> u64 { self.metadata().unwrap().len() } diff --git a/lib/wasi/src/syscalls/mod.rs b/lib/wasi/src/syscalls/mod.rs index d83889134..c5435995b 100644 --- a/lib/wasi/src/syscalls/mod.rs +++ b/lib/wasi/src/syscalls/mod.rs @@ -566,14 +566,42 @@ pub fn fd_filestat_set_times( inode.stat.st_atim = st_atim; } else if fst_flags & __WASI_FILESTAT_SET_ATIM_NOW != 0 { // set to current real time - unimplemented!("Set filestat time to the current real time"); + let now = std::time::SystemTime::now(); + let duration = wasi_try!( + now.duration_since(std::time::SystemTime::UNIX_EPOCH).ok(), + __WASI_EIO + ); + inode.stat.st_atim = duration.as_nanos() as __wasi_timestamp_t; + // TODO: set it for more than just files + match &mut inode.kind { + Kind::File { handle, .. } => { + if let Some(handle) = handle { + handle.set_last_accessed(duration.as_nanos() as __wasi_timestamp_t); + } + } + _ => {} + } } if fst_flags & __WASI_FILESTAT_SET_MTIM != 0 { inode.stat.st_mtim = st_mtim; } else if fst_flags & __WASI_FILESTAT_SET_MTIM_NOW != 0 { // set to current real time - unimplemented!("Set filestat time to the current real time"); + let now = std::time::SystemTime::now(); + let duration = wasi_try!( + now.duration_since(std::time::SystemTime::UNIX_EPOCH).ok(), + __WASI_EIO + ); + inode.stat.st_mtim = duration.as_nanos() as __wasi_timestamp_t; + // TODO: set it for more than just files + match &mut inode.kind { + Kind::File { handle, .. } => { + if let Some(handle) = handle { + handle.set_last_modified(duration.as_nanos() as __wasi_timestamp_t); + } + } + _ => {} + } } __WASI_ESUCCESS