1 #![expect(unsafe_op_in_unsafe_fn, reason = "old code, not worth updating yet")]
2
3 use std::{env, process, time::Duration};
4 use test_programs::preview1::{
5 TestConfig, assert_errno, assert_fs_time_eq, open_scratch_directory,
6 };
7
test_path_filestat(dir_fd: wasip1::Fd)8 unsafe fn test_path_filestat(dir_fd: wasip1::Fd) {
9 let cfg = TestConfig::from_env();
10 let fdflags = wasip1::FDFLAGS_APPEND;
11
12 // Create a file in the scratch directory.
13 let file_fd = wasip1::path_open(
14 dir_fd,
15 0,
16 "file",
17 wasip1::OFLAGS_CREAT,
18 wasip1::RIGHTS_FD_READ | wasip1::RIGHTS_FD_WRITE,
19 0,
20 // Pass some flags for later retrieval
21 fdflags,
22 )
23 .expect("opening a file");
24 assert!(
25 file_fd > libc::STDERR_FILENO as wasip1::Fd,
26 "file descriptor range check",
27 );
28
29 let fdstat = wasip1::fd_fdstat_get(file_fd).expect("fd_fdstat_get");
30 assert_eq!(
31 fdstat.fs_flags & wasip1::FDFLAGS_APPEND,
32 wasip1::FDFLAGS_APPEND,
33 "file should have the APPEND fdflag used to create the file"
34 );
35 assert_errno!(
36 wasip1::path_open(
37 dir_fd,
38 0,
39 "file",
40 0,
41 wasip1::RIGHTS_FD_READ | wasip1::RIGHTS_FD_WRITE,
42 0,
43 wasip1::FDFLAGS_SYNC,
44 )
45 .expect_err("FDFLAGS_SYNC not supported by platform"),
46 wasip1::ERRNO_NOTSUP
47 );
48
49 // Check file size
50 let file_stat = wasip1::path_filestat_get(dir_fd, 0, "file").expect("reading file stats");
51 assert_eq!(file_stat.size, 0, "file size should be 0");
52
53 // Check path_filestat_set_times
54 let new_mtim = Duration::from_nanos(file_stat.mtim) - 2 * cfg.fs_time_precision();
55 wasip1::path_filestat_set_times(
56 dir_fd,
57 0,
58 "file",
59 0,
60 new_mtim.as_nanos() as u64,
61 wasip1::FSTFLAGS_MTIM,
62 )
63 .expect("path_filestat_set_times should succeed");
64
65 let modified_file_stat = wasip1::path_filestat_get(dir_fd, 0, "file")
66 .expect("reading file stats after path_filestat_set_times");
67
68 assert_fs_time_eq!(
69 Duration::from_nanos(modified_file_stat.mtim),
70 new_mtim,
71 "mtim should change"
72 );
73
74 assert_errno!(
75 wasip1::path_filestat_set_times(
76 dir_fd,
77 0,
78 "file",
79 0,
80 new_mtim.as_nanos() as u64,
81 wasip1::FSTFLAGS_MTIM | wasip1::FSTFLAGS_MTIM_NOW,
82 )
83 .expect_err("MTIM and MTIM_NOW can't both be set"),
84 wasip1::ERRNO_INVAL
85 );
86
87 // check if the times were untouched
88 let unmodified_file_stat = wasip1::path_filestat_get(dir_fd, 0, "file")
89 .expect("reading file stats after ERRNO_INVAL fd_filestat_set_times");
90
91 assert_fs_time_eq!(
92 Duration::from_nanos(unmodified_file_stat.mtim),
93 new_mtim,
94 "mtim should not change"
95 );
96
97 // Invalid arguments to set_times:
98 assert_errno!(
99 wasip1::path_filestat_set_times(
100 dir_fd,
101 0,
102 "file",
103 0,
104 0,
105 wasip1::FSTFLAGS_ATIM | wasip1::FSTFLAGS_ATIM_NOW,
106 )
107 .expect_err("ATIM & ATIM_NOW can't both be set"),
108 wasip1::ERRNO_INVAL
109 );
110
111 wasip1::fd_close(file_fd).expect("closing a file");
112 wasip1::path_unlink_file(dir_fd, "file").expect("removing a file");
113 }
main()114 fn main() {
115 let mut args = env::args();
116 let prog = args.next().unwrap();
117 let arg = if let Some(arg) = args.next() {
118 arg
119 } else {
120 eprintln!("usage: {prog} <scratch directory>");
121 process::exit(1);
122 };
123
124 // Open scratch directory
125 let dir_fd = match open_scratch_directory(&arg) {
126 Ok(dir_fd) => dir_fd,
127 Err(err) => {
128 eprintln!("{err}");
129 process::exit(1)
130 }
131 };
132
133 // Run the tests.
134 unsafe { test_path_filestat(dir_fd) }
135 }
136