move more deps to cap-std-sync, define own SystemTimeSpec

This commit is contained in:
Pat Hickey
2021-01-21 12:35:55 -08:00
parent 61885b7071
commit fcd00f5de1
13 changed files with 160 additions and 167 deletions

4
Cargo.lock generated
View File

@@ -2516,18 +2516,14 @@ version = "0.22.0"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"bitflags", "bitflags",
"cap-fs-ext",
"cap-rand", "cap-rand",
"cap-std", "cap-std",
"cap-time-ext",
"cfg-if 1.0.0", "cfg-if 1.0.0",
"fs-set-times",
"libc", "libc",
"system-interface", "system-interface",
"thiserror", "thiserror",
"tracing", "tracing",
"wiggle", "wiggle",
"yanix 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]

View File

@@ -26,13 +26,9 @@ wiggle = { path = "../wiggle", default-features = false, version = "0.22.0" }
tracing = "0.1.19" tracing = "0.1.19"
system-interface = { version = "0.5", features = ["cap_std_impls"] } system-interface = { version = "0.5", features = ["cap_std_impls"] }
cap-std = "0.9" cap-std = "0.9"
cap-fs-ext = "0.9"
cap-time-ext = "0.9"
cap-rand = "0.9" cap-rand = "0.9"
fs-set-times = "0.2.2"
cfg-if = "1" cfg-if = "1"
bitflags = "1.2" bitflags = "1.2"
yanix = "0.22"
[badges] [badges]
maintenance = { status = "actively-developed" } maintenance = { status = "actively-developed" }

View File

@@ -0,0 +1,46 @@
use cap_std::time::{Duration, Instant, SystemTime};
use cap_time_ext::{MonotonicClockExt, SystemClockExt};
use wasi_c2::clocks::{WasiClocks, WasiMonotonicClock, WasiSystemClock};
pub struct SystemClock(cap_std::time::SystemClock);
impl SystemClock {
pub unsafe fn new() -> Self {
SystemClock(cap_std::time::SystemClock::new())
}
}
impl WasiSystemClock for SystemClock {
fn resolution(&self) -> Duration {
self.0.resolution()
}
fn now(&self, precision: Duration) -> SystemTime {
self.0.now_with(precision)
}
}
pub struct MonotonicClock(cap_std::time::MonotonicClock);
impl MonotonicClock {
pub unsafe fn new() -> Self {
MonotonicClock(cap_std::time::MonotonicClock::new())
}
}
impl WasiMonotonicClock for MonotonicClock {
fn resolution(&self) -> Duration {
self.0.resolution()
}
fn now(&self, precision: Duration) -> Instant {
self.0.now_with(precision)
}
}
pub fn clocks() -> WasiClocks {
let system = Box::new(unsafe { SystemClock::new() });
let monotonic = unsafe { cap_std::time::MonotonicClock::new() };
let creation_time = monotonic.now();
let monotonic = Box::new(MonotonicClock(monotonic));
WasiClocks {
system,
monotonic,
creation_time,
}
}

View File

@@ -197,7 +197,7 @@ impl WasiDir for Dir {
fn hard_link( fn hard_link(
&self, &self,
src_path: &str, src_path: &str,
symlink_follow: bool, symlink_follow: bool, // XXX not in cap-std yet
target_dir: &dyn WasiDir, target_dir: &dyn WasiDir,
target_path: &str, target_path: &str,
) -> Result<(), Error> { ) -> Result<(), Error> {
@@ -213,10 +213,22 @@ impl WasiDir for Dir {
fn set_times( fn set_times(
&self, &self,
path: &str, path: &str,
atime: Option<SystemTimeSpec>, atime: Option<wasi_c2::SystemTimeSpec>,
mtime: Option<SystemTimeSpec>, mtime: Option<wasi_c2::SystemTimeSpec>,
) -> Result<(), Error> { ) -> Result<(), Error> {
self.0.set_times(Path::new(path), atime, mtime)?; self.0.set_times(
Path::new(path),
convert_systimespec(atime),
convert_systimespec(mtime),
)?;
Ok(()) Ok(())
} }
} }
fn convert_systimespec(t: Option<wasi_c2::SystemTimeSpec>) -> Option<SystemTimeSpec> {
match t {
Some(wasi_c2::SystemTimeSpec::Absolute(t)) => Some(SystemTimeSpec::Absolute(t)),
Some(wasi_c2::SystemTimeSpec::SymbolicNow) => Some(SystemTimeSpec::SymbolicNow),
None => None,
}
}

View File

@@ -68,10 +68,11 @@ impl WasiFile for File {
} }
fn set_times( fn set_times(
&self, &self,
atime: Option<SystemTimeSpec>, atime: Option<wasi_c2::SystemTimeSpec>,
mtime: Option<SystemTimeSpec>, mtime: Option<wasi_c2::SystemTimeSpec>,
) -> Result<(), Error> { ) -> Result<(), Error> {
self.0.set_times(atime, mtime)?; self.0
.set_times(convert_systimespec(atime), convert_systimespec(mtime))?;
Ok(()) Ok(())
} }
fn read_vectored(&self, bufs: &mut [io::IoSliceMut]) -> Result<u64, Error> { fn read_vectored(&self, bufs: &mut [io::IoSliceMut]) -> Result<u64, Error> {
@@ -93,9 +94,6 @@ impl WasiFile for File {
fn seek(&self, pos: std::io::SeekFrom) -> Result<u64, Error> { fn seek(&self, pos: std::io::SeekFrom) -> Result<u64, Error> {
Ok(self.0.seek(pos)?) Ok(self.0.seek(pos)?)
} }
fn stream_position(&self) -> Result<u64, Error> {
Ok(self.0.stream_position()?)
}
fn peek(&self, buf: &mut [u8]) -> Result<u64, Error> { fn peek(&self, buf: &mut [u8]) -> Result<u64, Error> {
let n = self.0.peek(buf)?; let n = self.0.peek(buf)?;
Ok(n.try_into().map_err(|_| Error::Overflow)?) Ok(n.try_into().map_err(|_| Error::Overflow)?)
@@ -145,3 +143,10 @@ impl AsRawFd for File {
self.0.as_raw_fd() self.0.as_raw_fd()
} }
} }
pub fn convert_systimespec(t: Option<wasi_c2::SystemTimeSpec>) -> Option<SystemTimeSpec> {
match t {
Some(wasi_c2::SystemTimeSpec::Absolute(t)) => Some(SystemTimeSpec::Absolute(t.into_std())),
Some(wasi_c2::SystemTimeSpec::SymbolicNow) => Some(SystemTimeSpec::SymbolicNow),
None => None,
}
}

View File

@@ -1,3 +1,4 @@
pub mod clocks;
pub mod dir; pub mod dir;
pub mod file; pub mod file;
pub mod sched; pub mod sched;
@@ -7,7 +8,7 @@ use cap_rand::RngCore;
use std::cell::RefCell; use std::cell::RefCell;
use std::path::Path; use std::path::Path;
use std::rc::Rc; use std::rc::Rc;
use wasi_c2::{clocks::WasiClocks, table::Table, Error, WasiCtx, WasiFile}; use wasi_c2::{table::Table, Error, WasiCtx, WasiFile};
pub struct WasiCtxBuilder(wasi_c2::WasiCtxBuilder); pub struct WasiCtxBuilder(wasi_c2::WasiCtxBuilder);
@@ -15,7 +16,7 @@ impl WasiCtxBuilder {
pub fn new() -> Self { pub fn new() -> Self {
WasiCtxBuilder(WasiCtx::builder( WasiCtxBuilder(WasiCtx::builder(
random(), random(),
clocks(), clocks::clocks(),
Box::new(sched::SyncSched), Box::new(sched::SyncSched),
Rc::new(RefCell::new(Table::new())), Rc::new(RefCell::new(Table::new())),
)) ))
@@ -51,18 +52,6 @@ impl WasiCtxBuilder {
} }
} }
pub fn clocks() -> WasiClocks {
let system = Box::new(unsafe { cap_std::time::SystemClock::new() });
let monotonic = unsafe { cap_std::time::MonotonicClock::new() };
let creation_time = monotonic.now();
let monotonic = Box::new(monotonic);
WasiClocks {
system,
monotonic,
creation_time,
}
}
pub fn random() -> RefCell<Box<dyn RngCore>> { pub fn random() -> RefCell<Box<dyn RngCore>> {
RefCell::new(Box::new(unsafe { cap_rand::rngs::OsRng::default() })) RefCell::new(Box::new(unsafe { cap_rand::rngs::OsRng::default() }))
} }

View File

@@ -1,3 +1,4 @@
use crate::file::convert_systimespec;
use fs_set_times::SetTimes; use fs_set_times::SetTimes;
use std::any::Any; use std::any::Any;
use std::convert::TryInto; use std::convert::TryInto;
@@ -87,19 +88,16 @@ macro_rules! wasi_file_impl {
fn seek(&self, pos: std::io::SeekFrom) -> Result<u64, Error> { fn seek(&self, pos: std::io::SeekFrom) -> Result<u64, Error> {
Ok(self.0.seek(pos)?) Ok(self.0.seek(pos)?)
} }
fn stream_position(&self) -> Result<u64, Error> {
Ok(self.0.stream_position()?)
}
fn peek(&self, buf: &mut [u8]) -> Result<u64, Error> { fn peek(&self, buf: &mut [u8]) -> Result<u64, Error> {
let n = self.0.peek(buf)?; let n = self.0.peek(buf)?;
Ok(n.try_into().map_err(|_| Error::Overflow)?) Ok(n.try_into().map_err(|_| Error::Overflow)?)
} }
fn set_times( fn set_times(
&self, &self,
atime: Option<fs_set_times::SystemTimeSpec>, atime: Option<wasi_c2::SystemTimeSpec>,
mtime: Option<fs_set_times::SystemTimeSpec>, mtime: Option<wasi_c2::SystemTimeSpec>,
) -> Result<(), Error> { ) -> Result<(), Error> {
self.0.set_times(atime, mtime)?; self.0.set_times(convert_systimespec(atime), convert_systimespec(mtime))?;
Ok(()) Ok(())
} }
$additional $additional

View File

@@ -1,34 +1,20 @@
use cap_std::time::{Duration, Instant, MonotonicClock, SystemClock, SystemTime}; use cap_std::time::{Duration, Instant, SystemTime};
use cap_time_ext::{MonotonicClockExt, SystemClockExt};
pub enum SystemTimeSpec {
SymbolicNow,
Absolute(SystemTime),
}
pub trait WasiSystemClock { pub trait WasiSystemClock {
fn resolution(&self) -> Duration; fn resolution(&self) -> Duration;
fn now(&self, precision: Duration) -> SystemTime; fn now(&self, precision: Duration) -> SystemTime;
} }
impl WasiSystemClock for SystemClock {
fn resolution(&self) -> Duration {
SystemClockExt::resolution(self)
}
fn now(&self, precision: Duration) -> SystemTime {
self.now_with(precision)
}
}
pub trait WasiMonotonicClock { pub trait WasiMonotonicClock {
fn resolution(&self) -> Duration; fn resolution(&self) -> Duration;
fn now(&self, precision: Duration) -> Instant; fn now(&self, precision: Duration) -> Instant;
} }
impl WasiMonotonicClock for MonotonicClock {
fn resolution(&self) -> Duration {
MonotonicClockExt::resolution(self)
}
fn now(&self, precision: Duration) -> Instant {
self.now_with(precision)
}
}
pub struct WasiClocks { pub struct WasiClocks {
pub system: Box<dyn WasiSystemClock>, pub system: Box<dyn WasiSystemClock>,
pub monotonic: Box<dyn WasiMonotonicClock>, pub monotonic: Box<dyn WasiMonotonicClock>,

View File

@@ -1,7 +1,6 @@
use crate::error::Error;
use crate::file::{FdFlags, FileCaps, FileType, Filestat, OFlags, WasiFile}; use crate::file::{FdFlags, FileCaps, FileType, Filestat, OFlags, WasiFile};
use crate::{Error, SystemTimeSpec};
use bitflags::bitflags; use bitflags::bitflags;
use cap_fs_ext::SystemTimeSpec;
use std::any::Any; use std::any::Any;
use std::cell::Ref; use std::cell::Ref;
use std::ops::Deref; use std::ops::Deref;

View File

@@ -1,42 +1,43 @@
use crate::Error; use crate::{Error, SystemTimeSpec};
use bitflags::bitflags; use bitflags::bitflags;
use fs_set_times::SystemTimeSpec;
use std::any::Any; use std::any::Any;
use std::cell::Ref; use std::cell::Ref;
use std::ops::Deref; use std::ops::Deref;
pub trait WasiFile { pub trait WasiFile {
fn as_any(&self) -> &dyn Any; fn as_any(&self) -> &dyn Any;
fn datasync(&self) -> Result<(), Error>; fn datasync(&self) -> Result<(), Error>; // write op
fn sync(&self) -> Result<(), Error>; fn sync(&self) -> Result<(), Error>; // file op
fn get_filetype(&self) -> Result<FileType, Error>; fn get_filetype(&self) -> Result<FileType, Error>; // file op
fn get_fdflags(&self) -> Result<FdFlags, Error>; fn get_fdflags(&self) -> Result<FdFlags, Error>; // file op
fn set_fdflags(&self, _flags: FdFlags) -> Result<(), Error>; fn set_fdflags(&self, _flags: FdFlags) -> Result<(), Error>;
fn get_filestat(&self) -> Result<Filestat, Error>; fn get_filestat(&self) -> Result<Filestat, Error>; // split out get_length as a read & write op, rest is a file op
fn set_filestat_size(&self, _size: u64) -> Result<(), Error>; fn set_filestat_size(&self, _size: u64) -> Result<(), Error>; // write op
fn advise( fn advise(
&self, &self,
offset: u64, offset: u64,
len: u64, len: u64,
advice: system_interface::fs::Advice, advice: system_interface::fs::Advice,
) -> Result<(), Error>; ) -> Result<(), Error>; // file op
fn allocate(&self, offset: u64, len: u64) -> Result<(), Error>; fn allocate(&self, offset: u64, len: u64) -> Result<(), Error>; // write op
fn set_times( fn set_times(
&self, &self,
atime: Option<SystemTimeSpec>, atime: Option<SystemTimeSpec>,
mtime: Option<SystemTimeSpec>, mtime: Option<SystemTimeSpec>,
) -> Result<(), Error>; ) -> Result<(), Error>;
fn read_vectored(&self, bufs: &mut [std::io::IoSliceMut]) -> Result<u64, Error>; fn read_vectored(&self, bufs: &mut [std::io::IoSliceMut]) -> Result<u64, Error>; // read op
fn read_vectored_at(&self, bufs: &mut [std::io::IoSliceMut], offset: u64) fn read_vectored_at(&self, bufs: &mut [std::io::IoSliceMut], offset: u64)
-> Result<u64, Error>; -> Result<u64, Error>; // file op
fn write_vectored(&self, bufs: &[std::io::IoSlice]) -> Result<u64, Error>; fn write_vectored(&self, bufs: &[std::io::IoSlice]) -> Result<u64, Error>; // write op
fn write_vectored_at(&self, bufs: &[std::io::IoSlice], offset: u64) -> Result<u64, Error>; fn write_vectored_at(&self, bufs: &[std::io::IoSlice], offset: u64) -> Result<u64, Error>; // file op
fn seek(&self, pos: std::io::SeekFrom) -> Result<u64, Error>; fn seek(&self, pos: std::io::SeekFrom) -> Result<u64, Error>; // file op that generates a new stream from a file will supercede this
fn stream_position(&self) -> Result<u64, Error>; fn peek(&self, buf: &mut [u8]) -> Result<u64, Error>; // read op
fn peek(&self, buf: &mut [u8]) -> Result<u64, Error>; fn num_ready_bytes(&self) -> Result<u64, Error>; // read op
fn num_ready_bytes(&self) -> Result<u64, Error>;
} }
// XXX we will add pipes to wasi - lets add it to this internal enum and present them as
// Unknown to old wasis
// XXX put the enum variants in same order as WASI so conversion funcs are no-op
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone)]
pub enum FileType { pub enum FileType {
Directory, Directory,
@@ -74,7 +75,7 @@ pub struct Filestat {
pub inode: u64, pub inode: u64,
pub filetype: FileType, pub filetype: FileType,
pub nlink: u64, pub nlink: u64,
pub size: u64, pub size: u64, // this is a read field, the rest are file fields
pub atim: Option<std::time::SystemTime>, pub atim: Option<std::time::SystemTime>,
pub mtim: Option<std::time::SystemTime>, pub mtim: Option<std::time::SystemTime>,
pub ctim: Option<std::time::SystemTime>, pub ctim: Option<std::time::SystemTime>,

View File

@@ -12,7 +12,7 @@ pub mod snapshots;
mod string_array; mod string_array;
pub mod table; pub mod table;
pub use cap_fs_ext::SystemTimeSpec; pub use clocks::SystemTimeSpec;
pub use ctx::{WasiCtx, WasiCtxBuilder}; pub use ctx::{WasiCtx, WasiCtxBuilder};
pub use dir::{DirCaps, ReaddirCursor, ReaddirEntity, WasiDir}; pub use dir::{DirCaps, ReaddirCursor, ReaddirEntity, WasiDir};
pub use error::Error; pub use error::Error;

View File

@@ -9,8 +9,10 @@
//! Some convenience constructors are included for common backing types like `Vec<u8>` and `String`, //! Some convenience constructors are included for common backing types like `Vec<u8>` and `String`,
//! but the virtual pipes can be instantiated with any `Read` or `Write` type. //! but the virtual pipes can be instantiated with any `Read` or `Write` type.
//! //!
use crate::file::{FdFlags, FileType, Filestat, WasiFile}; use crate::{
use crate::Error; file::{FdFlags, FileType, Filestat, WasiFile},
Error, SystemTimeSpec,
};
use std::any::Any; use std::any::Any;
use std::convert::TryInto; use std::convert::TryInto;
use std::io::{self, Read, Write}; use std::io::{self, Read, Write};
@@ -152,16 +154,13 @@ impl<R: Read + Any> WasiFile for ReadPipe<R> {
fn seek(&self, pos: std::io::SeekFrom) -> Result<u64, Error> { fn seek(&self, pos: std::io::SeekFrom) -> Result<u64, Error> {
Err(Error::Badf) Err(Error::Badf)
} }
fn stream_position(&self) -> Result<u64, Error> {
Err(Error::Badf)
}
fn peek(&self, buf: &mut [u8]) -> Result<u64, Error> { fn peek(&self, buf: &mut [u8]) -> Result<u64, Error> {
Err(Error::Badf) Err(Error::Badf)
} }
fn set_times( fn set_times(
&self, &self,
atime: Option<fs_set_times::SystemTimeSpec>, atime: Option<SystemTimeSpec>,
mtime: Option<fs_set_times::SystemTimeSpec>, mtime: Option<SystemTimeSpec>,
) -> Result<(), Error> { ) -> Result<(), Error> {
Err(Error::Badf) Err(Error::Badf)
} }
@@ -291,16 +290,13 @@ impl<W: Write + Any> WasiFile for WritePipe<W> {
fn seek(&self, pos: std::io::SeekFrom) -> Result<u64, Error> { fn seek(&self, pos: std::io::SeekFrom) -> Result<u64, Error> {
Err(Error::Badf) Err(Error::Badf)
} }
fn stream_position(&self) -> Result<u64, Error> {
Err(Error::Badf)
}
fn peek(&self, buf: &mut [u8]) -> Result<u64, Error> { fn peek(&self, buf: &mut [u8]) -> Result<u64, Error> {
Err(Error::Badf) Err(Error::Badf)
} }
fn set_times( fn set_times(
&self, &self,
atime: Option<fs_set_times::SystemTimeSpec>, atime: Option<SystemTimeSpec>,
mtime: Option<fs_set_times::SystemTimeSpec>, mtime: Option<SystemTimeSpec>,
) -> Result<(), Error> { ) -> Result<(), Error> {
Err(Error::Badf) Err(Error::Badf)
} }

View File

@@ -1,14 +1,17 @@
#![allow(unused_variables)] #![allow(unused_variables)]
use crate::dir::{ use crate::{
DirCaps, DirEntry, DirEntryExt, DirFdStat, ReaddirCursor, ReaddirEntity, TableDirExt, dir::{DirCaps, DirEntry, DirEntryExt, DirFdStat, ReaddirCursor, ReaddirEntity, TableDirExt},
file::{
FdFlags, FdStat, FileCaps, FileEntry, FileEntryExt, FileType, Filestat, OFlags,
TableFileExt,
},
sched::{
subscription::{RwEventFlags, SubscriptionResult},
Poll,
},
Error, SystemTimeSpec, WasiCtx,
}; };
use crate::file::{ use cap_std::time::{Duration, SystemClock};
FdFlags, FdStat, FileCaps, FileEntry, FileEntryExt, FileType, Filestat, OFlags, TableFileExt,
};
use crate::sched::subscription::{RwEventFlags, SubscriptionResult};
use crate::sched::Poll;
use crate::{Error, WasiCtx};
use fs_set_times::SystemTimeSpec;
use std::cell::{Ref, RefMut}; use std::cell::{Ref, RefMut};
use std::convert::{TryFrom, TryInto}; use std::convert::{TryFrom, TryInto};
use std::io::{IoSlice, IoSliceMut}; use std::io::{IoSlice, IoSliceMut};
@@ -172,7 +175,6 @@ impl<'a> wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiCtx {
id: types::Clockid, id: types::Clockid,
precision: types::Timestamp, precision: types::Timestamp,
) -> Result<types::Timestamp, Error> { ) -> Result<types::Timestamp, Error> {
use cap_std::time::Duration;
let precision = Duration::from_nanos(precision); let precision = Duration::from_nanos(precision);
match id { match id {
types::Clockid::Realtime => { types::Clockid::Realtime => {
@@ -344,36 +346,6 @@ 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);
} }
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
};
table
.get_file(fd)
.expect("checked that entry is file")
.get_cap(FileCaps::FILESTAT_SET_TIMES)?
.set_times(atim, mtim)
} else if table.is::<DirEntry>(fd) {
use cap_std::time::{Duration, SystemClock};
use cap_fs_ext::SystemTimeSpec;
let atim = if set_atim { let atim = if set_atim {
Some(SystemTimeSpec::Absolute( Some(SystemTimeSpec::Absolute(
SystemClock::UNIX_EPOCH + Duration::from_nanos(atim), SystemClock::UNIX_EPOCH + Duration::from_nanos(atim),
@@ -392,7 +364,13 @@ impl<'a> wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiCtx {
} else { } else {
None None
}; };
if table.is::<FileEntry>(fd) {
table
.get_file(fd)
.expect("checked that entry is file")
.get_cap(FileCaps::FILESTAT_SET_TIMES)?
.set_times(atim, mtim)
} else if table.is::<DirEntry>(fd) {
table table
.get_dir(fd) .get_dir(fd)
.expect("checked that entry is dir") .expect("checked that entry is dir")
@@ -599,6 +577,7 @@ impl<'a> wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiCtx {
} }
fn fd_tell(&self, fd: types::Fd) -> Result<types::Filesize, Error> { fn fd_tell(&self, fd: types::Fd) -> Result<types::Filesize, Error> {
// XXX should this be stream_position?
let offset = self let offset = self
.table() .table()
.get_file(u32::from(fd))? .get_file(u32::from(fd))?
@@ -694,7 +673,6 @@ 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> {
// XXX DRY these are in fd_filestat_set_times twice!
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);
@@ -702,27 +680,19 @@ 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);
} }
use cap_fs_ext::SystemTimeSpec; fn systimespec(set: bool, ts: types::Timestamp, now: bool) -> Option<SystemTimeSpec> {
use cap_std::time::{Duration, SystemClock}; if set {
let atim = if set_atim {
Some(SystemTimeSpec::Absolute( Some(SystemTimeSpec::Absolute(
SystemClock::UNIX_EPOCH + Duration::from_nanos(atim), SystemClock::UNIX_EPOCH + Duration::from_nanos(ts),
)) ))
} else if set_atim_now { } else if now {
Some(SystemTimeSpec::SymbolicNow) Some(SystemTimeSpec::SymbolicNow)
} else { } else {
None None
}; }
let mtim = if set_mtim { }
Some(SystemTimeSpec::Absolute( let atim = systimespec(set_atim, atim, set_atim_now);
SystemClock::UNIX_EPOCH + Duration::from_nanos(mtim), let mtim = systimespec(set_mtim, mtim, set_mtim_now);
))
} else if set_mtim_now {
Some(SystemTimeSpec::SymbolicNow)
} else {
None
};
self.table() self.table()
.get_dir(u32::from(dirfd))? .get_dir(u32::from(dirfd))?
.get_cap(DirCaps::PATH_FILESTAT_SET_TIMES)? .get_cap(DirCaps::PATH_FILESTAT_SET_TIMES)?
@@ -893,7 +863,6 @@ impl<'a> wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiCtx {
return Err(Error::Inval); return Err(Error::Inval);
} }
use cap_std::time::Duration;
let table = self.table(); let table = self.table();
let mut poll = Poll::new(); let mut poll = Poll::new();