dir: add set times

This commit is contained in:
Pat Hickey
2021-01-05 14:24:02 -08:00
parent 16eff680e2
commit ce13cd9e77
3 changed files with 63 additions and 25 deletions

View File

@@ -29,7 +29,7 @@ cap-std = "0.8"
cap-fs-ext = "0.8" cap-fs-ext = "0.8"
cap-time-ext = "0.8" cap-time-ext = "0.8"
cap-rand = "0.8" cap-rand = "0.8"
fs-set-times = "0.2.1" fs-set-times = "0.2.2"
cfg-if = "1" cfg-if = "1"
[badges] [badges]

View File

@@ -1,5 +1,6 @@
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 cap_fs_ext::SystemTimeSpec;
use std::any::Any; use std::any::Any;
use std::convert::TryInto; use std::convert::TryInto;
use std::ops::Deref; use std::ops::Deref;
@@ -35,6 +36,12 @@ pub trait WasiDir {
target_dir: &dyn WasiDir, target_dir: &dyn WasiDir,
target_path: &str, target_path: &str,
) -> Result<(), Error>; ) -> Result<(), Error>;
fn set_times(
&self,
path: &str,
atime: Option<SystemTimeSpec>,
mtime: Option<SystemTimeSpec>,
) -> Result<(), Error>;
} }
pub(crate) struct DirEntry { 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))?; self.hard_link(Path::new(src_path), target_dir, Path::new(target_path))?;
Ok(()) Ok(())
} }
fn set_times(
&self,
path: &str,
atime: Option<SystemTimeSpec>,
mtime: Option<SystemTimeSpec>,
) -> Result<(), Error> {
cap_fs_ext::DirExt::set_times(self, Path::new(path), atime, mtime)?;
Ok(())
}
} }

View File

@@ -322,8 +322,9 @@ impl<'a> wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiCtx {
mtim: types::Timestamp, mtim: types::Timestamp,
fst_flags: types::Fstflags, fst_flags: types::Fstflags,
) -> Result<(), Error> { ) -> Result<(), Error> {
use std::time::{Duration, UNIX_EPOCH}; let fd = u32::from(fd);
// Validate flags, transform into well-structured arguments let table = self.table();
// Validate flags
let set_atim = fst_flags.contains(&types::Fstflags::ATIM); let set_atim = fst_flags.contains(&types::Fstflags::ATIM);
let set_atim_now = fst_flags.contains(&types::Fstflags::ATIM_NOW); let set_atim_now = fst_flags.contains(&types::Fstflags::ATIM_NOW);
let set_mtim = fst_flags.contains(&types::Fstflags::MTIM); 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) { if (set_atim && set_atim_now) || (set_mtim && set_mtim_now) {
return Err(Error::Inval); 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::<FileEntry>(fd) { if table.is::<FileEntry>(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<FileEntry> = table.get(fd).unwrap(); let file_entry: Ref<FileEntry> = table.get(fd).unwrap();
let f = file_entry.get_cap(FileCaps::FILESTAT_SET_TIMES)?; let f = file_entry.get_cap(FileCaps::FILESTAT_SET_TIMES)?;
f.set_times(atim, mtim)?; f.set_times(atim, mtim)?;
Ok(()) Ok(())
} else if table.is::<DirEntry>(fd) { } else if table.is::<DirEntry>(fd) {
use cap_std::time::{Duration, SystemClock};
let dir_entry: Ref<DirEntry> = table.get(fd).unwrap(); let dir_entry: Ref<DirEntry> = table.get(fd).unwrap();
let d = dir_entry.get_cap(DirCaps::FILESTAT_SET_TIMES)?; 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 { } else {
Err(Error::Badf) Err(Error::Badf)
} }