Skip to content

Commit 2438df7

Browse files
chenyukangjoshtriplett
authored andcommitted
support fs::set_times for wasi
1 parent 46c6f0a commit 2438df7

File tree

1 file changed

+37
-18
lines changed

1 file changed

+37
-18
lines changed

library/std/src/sys/fs/wasi.rs

Lines changed: 37 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -536,17 +536,9 @@ impl File {
536536
}
537537

538538
pub fn set_times(&self, times: FileTimes) -> io::Result<()> {
539-
let to_timestamp = |time: Option<SystemTime>| match time {
540-
Some(time) if let Some(ts) = time.to_wasi_timestamp() => Ok(ts),
541-
Some(_) => Err(io::const_error!(
542-
io::ErrorKind::InvalidInput,
543-
"timestamp is too large to set as a file time",
544-
)),
545-
None => Ok(0),
546-
};
547539
self.fd.filestat_set_times(
548-
to_timestamp(times.accessed)?,
549-
to_timestamp(times.modified)?,
540+
to_wasi_timestamp_or_now(times.accessed)?,
541+
to_wasi_timestamp_or_now(times.modified)?,
550542
times.accessed.map_or(0, |_| wasi::FSTFLAGS_ATIM)
551543
| times.modified.map_or(0, |_| wasi::FSTFLAGS_MTIM),
552544
)
@@ -643,16 +635,43 @@ pub fn set_perm(_p: &Path, _perm: FilePermissions) -> io::Result<()> {
643635
unsupported()
644636
}
645637

646-
pub fn set_times(_p: &Path, _times: FileTimes) -> io::Result<()> {
647-
// File times haven't been fully figured out in wasi yet, so this is
648-
// likely temporary
649-
unsupported()
638+
#[inline(always)]
639+
pub fn set_times(p: &Path, times: FileTimes) -> io::Result<()> {
640+
let (dir, file) = open_parent(p)?;
641+
set_times_impl(&dir, &file, times, wasi::LOOKUPFLAGS_SYMLINK_FOLLOW)
650642
}
651643

652-
pub fn set_times_nofollow(_p: &Path, _times: FileTimes) -> io::Result<()> {
653-
// File times haven't been fully figured out in wasi yet, so this is
654-
// likely temporary
655-
unsupported()
644+
#[inline(always)]
645+
pub fn set_times_nofollow(p: &Path, times: FileTimes) -> io::Result<()> {
646+
let (dir, file) = open_parent(p)?;
647+
set_times_impl(&dir, &file, times, 0)
648+
}
649+
650+
fn to_wasi_timestamp_or_now(time: Option<SystemTime>) -> io::Result<wasi::Timestamp> {
651+
match time {
652+
Some(time) if let Some(ts) = time.to_wasi_timestamp() => Ok(ts),
653+
Some(_) => Err(io::const_error!(
654+
io::ErrorKind::InvalidInput,
655+
"timestamp is too large to set as a file time",
656+
)),
657+
None => Ok(0),
658+
}
659+
}
660+
661+
fn set_times_impl(
662+
fd: &WasiFd,
663+
path: &Path,
664+
times: FileTimes,
665+
flags: wasi::Lookupflags,
666+
) -> io::Result<()> {
667+
fd.path_filestat_set_times(
668+
flags,
669+
osstr2str(path.as_ref())?,
670+
to_wasi_timestamp_or_now(times.accessed)?,
671+
to_wasi_timestamp_or_now(times.modified)?,
672+
times.accessed.map_or(0, |_| wasi::FSTFLAGS_ATIM)
673+
| times.modified.map_or(0, |_| wasi::FSTFLAGS_MTIM),
674+
)
656675
}
657676

658677
pub fn rmdir(p: &Path) -> io::Result<()> {

0 commit comments

Comments
 (0)