Browse Source

adapter: change logic around interpeting ATIM and ATIM_NOW (and MTIM equiv) to be consistient with upstream

in wasi-common preview1, ATIM and ATIM_NOW (and MTIM and MTIM now) were mutually exclusive and would result in an INVAL error, whereas in the adapter previously, ATIM_NOW implied ATIM, but would silently do nothing if ATIM was not set.

I decided to be consistient with the upstream behavior here because it is pretty arbitrary and I don't think there's a good reason to break compatibility.

This fixes the `path_filestat` test.
pull/6374/head
Pat Hickey 2 years ago
parent
commit
b0fed76389
  1. 82
      src/lib.rs

82
src/lib.rs

@ -618,6 +618,21 @@ pub unsafe extern "C" fn fd_filestat_set_size(fd: Fd, size: Filesize) -> Errno {
})
}
fn systimespec(set: bool, ts: Timestamp, now: bool) -> Result<filesystem::NewTimestamp, Errno> {
if set && now {
Err(wasi::ERRNO_INVAL)
} else if set {
Ok(filesystem::NewTimestamp::Timestamp(filesystem::Datetime {
seconds: ts / 1_000_000_000,
nanoseconds: (ts % 1_000_000_000) as _,
}))
} else if now {
Ok(filesystem::NewTimestamp::Now)
} else {
Ok(filesystem::NewTimestamp::NoChange)
}
}
/// Adjust the timestamps of an open file or directory.
/// Note: This is similar to `futimens` in POSIX.
#[no_mangle]
@ -627,30 +642,17 @@ pub unsafe extern "C" fn fd_filestat_set_times(
mtim: Timestamp,
fst_flags: Fstflags,
) -> Errno {
let atim =
if fst_flags & (FSTFLAGS_ATIM | FSTFLAGS_ATIM_NOW) == (FSTFLAGS_ATIM | FSTFLAGS_ATIM_NOW) {
filesystem::NewTimestamp::Now
} else if fst_flags & FSTFLAGS_ATIM == FSTFLAGS_ATIM {
filesystem::NewTimestamp::Timestamp(filesystem::Datetime {
seconds: atim / 1_000_000_000,
nanoseconds: (atim % 1_000_000_000) as _,
})
} else {
filesystem::NewTimestamp::NoChange
};
let mtim =
if fst_flags & (FSTFLAGS_MTIM | FSTFLAGS_MTIM_NOW) == (FSTFLAGS_MTIM | FSTFLAGS_MTIM_NOW) {
filesystem::NewTimestamp::Now
} else if fst_flags & FSTFLAGS_MTIM == FSTFLAGS_MTIM {
filesystem::NewTimestamp::Timestamp(filesystem::Datetime {
seconds: mtim / 1_000_000_000,
nanoseconds: (mtim % 1_000_000_000) as _,
})
} else {
filesystem::NewTimestamp::NoChange
};
State::with(|state| {
let atim = systimespec(
fst_flags & FSTFLAGS_ATIM == FSTFLAGS_ATIM,
atim,
fst_flags & FSTFLAGS_ATIM_NOW == FSTFLAGS_ATIM_NOW,
)?;
let mtim = systimespec(
fst_flags & FSTFLAGS_MTIM == FSTFLAGS_MTIM,
mtim,
fst_flags & FSTFLAGS_MTIM_NOW == FSTFLAGS_MTIM_NOW,
)?;
let ds = state.descriptors();
let file = ds.get_file(fd)?;
filesystem::set_times(file.fd, atim, mtim)?;
@ -1260,33 +1262,21 @@ pub unsafe extern "C" fn path_filestat_set_times(
mtim: Timestamp,
fst_flags: Fstflags,
) -> Errno {
let atim =
if fst_flags & (FSTFLAGS_ATIM | FSTFLAGS_ATIM_NOW) == (FSTFLAGS_ATIM | FSTFLAGS_ATIM_NOW) {
filesystem::NewTimestamp::Now
} else if fst_flags & FSTFLAGS_ATIM == FSTFLAGS_ATIM {
filesystem::NewTimestamp::Timestamp(filesystem::Datetime {
seconds: atim / 1_000_000_000,
nanoseconds: (atim % 1_000_000_000) as _,
})
} else {
filesystem::NewTimestamp::NoChange
};
let mtim =
if fst_flags & (FSTFLAGS_MTIM | FSTFLAGS_MTIM_NOW) == (FSTFLAGS_MTIM | FSTFLAGS_MTIM_NOW) {
filesystem::NewTimestamp::Now
} else if fst_flags & FSTFLAGS_MTIM == FSTFLAGS_MTIM {
filesystem::NewTimestamp::Timestamp(filesystem::Datetime {
seconds: mtim / 1_000_000_000,
nanoseconds: (mtim % 1_000_000_000) as _,
})
} else {
filesystem::NewTimestamp::NoChange
};
let path = slice::from_raw_parts(path_ptr, path_len);
let at_flags = at_flags_from_lookupflags(flags);
State::with(|state| {
let atim = systimespec(
fst_flags & FSTFLAGS_ATIM == FSTFLAGS_ATIM,
atim,
fst_flags & FSTFLAGS_ATIM_NOW == FSTFLAGS_ATIM_NOW,
)?;
let mtim = systimespec(
fst_flags & FSTFLAGS_MTIM == FSTFLAGS_MTIM,
mtim,
fst_flags & FSTFLAGS_MTIM_NOW == FSTFLAGS_MTIM_NOW,
)?;
let ds = state.descriptors();
let file = ds.get_dir(fd)?;
filesystem::set_times_at(file.fd, at_flags, path, atim, mtim)?;

Loading…
Cancel
Save