use crate::{init, test::common::libc, wasi};
unsafe fn test_fd_filestat_set_size_rw(dir_fd: wasi::Fd) {
unsafe {
let file_fd = wasi::path_open(
dir_fd,
0,
"file",
wasi::OFLAGS_CREAT,
wasi::RIGHTS_FD_READ | wasi::RIGHTS_FD_WRITE,
0,
0,
)
.expect("failed to create file");
assert!(
file_fd > libc::STDERR_FILENO as wasi::Fd,
"file descriptor range check",
);
let stat = wasi::fd_filestat_get(file_fd).expect("failed filestat");
assert_eq!(stat.size, 0, "file size should be 0");
wasi::fd_filestat_set_size(file_fd, 100).expect("fd_filestat_set_size");
let stat = wasi::fd_filestat_get(file_fd).expect("failed filestat 2");
assert_eq!(stat.size, 100, "file size should be 100");
wasi::fd_close(file_fd).expect("failed to close fd");
wasi::path_unlink_file(dir_fd, "file").expect("failed to remove file");
}
}
unsafe fn test_fd_filestat_set_size_ro(dir_fd: wasi::Fd) {
unsafe {
let file_fd = wasi::path_open(dir_fd, 0, "file", wasi::OFLAGS_CREAT, 0, 0, 0)
.expect("failed to create file");
wasi::fd_close(file_fd).expect("failed to close fd");
let file_fd = wasi::path_open(dir_fd, 0, "file", 0, wasi::RIGHTS_FD_READ, 0, 0)
.expect("failed to create file");
let stat = wasi::fd_filestat_get(file_fd).expect("failed filestat");
assert_eq!(stat.size, 0, "file size should be 0");
assert_eq!(
wasi::fd_filestat_set_size(file_fd, 100)
.expect_err("fd_filestat_set_size should error when file is opened read-only"),
wasi::ERRNO_INVAL
);
let stat = wasi::fd_filestat_get(file_fd).expect("failed filestat 2");
assert_eq!(stat.size, 0, "file size should remain 0");
wasi::fd_close(file_fd).expect("failed to close fd");
wasi::path_unlink_file(dir_fd, "file").expect("failed to remove file");
}
}
unsafe fn test_fd_filestat_set_times(dir_fd: wasi::Fd, rights: wasi::Rights) {
unsafe {
let resolution = wasi::clock_res_get(wasi::CLOCKID_MONOTONIC).unwrap();
let file_fd = wasi::path_open(dir_fd, 0, "file", wasi::OFLAGS_CREAT, 0, 0, 0)
.expect("failed to create file");
wasi::fd_close(file_fd).expect("failed to close fd");
let file_fd =
wasi::path_open(dir_fd, 0, "file", 0, rights, 0, 0).expect("failed to create file");
let stat = wasi::fd_filestat_get(file_fd).expect("failed filestat 2");
let old_atim = stat.atim;
let new_mtim = stat.mtim - resolution * 2;
wasi::fd_filestat_set_times(file_fd, new_mtim, new_mtim, wasi::FSTFLAGS_MTIM)
.expect("fd_filestat_set_times");
let stat = wasi::fd_filestat_get(file_fd).expect("failed filestat 3");
assert_eq!(stat.size, 0, "file size should remain unchanged at 0");
assert_eq!(stat.mtim, new_mtim, "mtim should change");
assert_eq!(stat.atim, old_atim, "atim should not change");
wasi::fd_close(file_fd).expect("failed to close fd");
wasi::path_unlink_file(dir_fd, "file").expect("failed to remove file");
}
}
#[test]
fn fd_filestat_test_tests() {
init(&[], &[]);
let dir_fd = 3;
unsafe { test_fd_filestat_set_size_rw(dir_fd) }
unsafe { test_fd_filestat_set_size_ro(dir_fd) }
unsafe { test_fd_filestat_set_times(dir_fd, wasi::RIGHTS_FD_READ) }
unsafe { test_fd_filestat_set_times(dir_fd, wasi::RIGHTS_FD_READ | wasi::RIGHTS_FD_WRITE) }
}