1 #![expect(unsafe_op_in_unsafe_fn, reason = "old code, not worth updating yet")]
2 
3 use std::{env, process};
4 use test_programs::preview1::open_scratch_directory;
5 
test_fd_fdstat_set_flags(dir_fd: wasip1::Fd)6 unsafe fn test_fd_fdstat_set_flags(dir_fd: wasip1::Fd) {
7     const FILE_NAME: &str = "file";
8     let data = &[0u8; 100];
9 
10     let file_fd = wasip1::path_open(
11         dir_fd,
12         0,
13         FILE_NAME,
14         wasip1::OFLAGS_CREAT,
15         wasip1::RIGHTS_FD_READ | wasip1::RIGHTS_FD_WRITE,
16         0,
17         wasip1::FDFLAGS_APPEND,
18     )
19     .expect("opening a file");
20 
21     // Write some data and then verify the written data
22     assert_eq!(
23         wasip1::fd_write(
24             file_fd,
25             &[wasip1::Ciovec {
26                 buf: data.as_ptr(),
27                 buf_len: data.len(),
28             }],
29         )
30         .expect("writing to a file"),
31         data.len(),
32         "should write {} bytes",
33         data.len(),
34     );
35 
36     wasip1::fd_seek(file_fd, 0, wasip1::WHENCE_SET).expect("seeking file");
37 
38     let buffer = &mut [0u8; 100];
39 
40     assert_eq!(
41         wasip1::fd_read(
42             file_fd,
43             &[wasip1::Iovec {
44                 buf: buffer.as_mut_ptr(),
45                 buf_len: buffer.len(),
46             }]
47         )
48         .expect("reading file"),
49         buffer.len(),
50         "should read {} bytes",
51         buffer.len()
52     );
53 
54     assert_eq!(&data[..], &buffer[..]);
55 
56     let data = &[1u8; 100];
57 
58     // Seek back to the start to ensure we're in append-only mode
59     wasip1::fd_seek(file_fd, 0, wasip1::WHENCE_SET).expect("seeking file");
60 
61     assert_eq!(
62         wasip1::fd_write(
63             file_fd,
64             &[wasip1::Ciovec {
65                 buf: data.as_ptr(),
66                 buf_len: data.len(),
67             }],
68         )
69         .expect("writing to a file"),
70         data.len(),
71         "should write {} bytes",
72         data.len(),
73     );
74 
75     wasip1::fd_seek(file_fd, 100, wasip1::WHENCE_SET).expect("seeking file");
76 
77     assert_eq!(
78         wasip1::fd_read(
79             file_fd,
80             &[wasip1::Iovec {
81                 buf: buffer.as_mut_ptr(),
82                 buf_len: buffer.len(),
83             }]
84         )
85         .expect("reading file"),
86         buffer.len(),
87         "should read {} bytes",
88         buffer.len()
89     );
90 
91     assert_eq!(&data[..], &buffer[..]);
92 
93     wasip1::fd_fdstat_set_flags(file_fd, 0).expect("disabling flags");
94 
95     // Overwrite some existing data to ensure the append mode is now off
96     wasip1::fd_seek(file_fd, 0, wasip1::WHENCE_SET).expect("seeking file");
97 
98     let data = &[2u8; 100];
99 
100     assert_eq!(
101         wasip1::fd_write(
102             file_fd,
103             &[wasip1::Ciovec {
104                 buf: data.as_ptr(),
105                 buf_len: data.len(),
106             }],
107         )
108         .expect("writing to a file"),
109         data.len(),
110         "should write {} bytes",
111         data.len(),
112     );
113 
114     wasip1::fd_seek(file_fd, 0, wasip1::WHENCE_SET).expect("seeking file");
115 
116     assert_eq!(
117         wasip1::fd_read(
118             file_fd,
119             &[wasip1::Iovec {
120                 buf: buffer.as_mut_ptr(),
121                 buf_len: buffer.len(),
122             }]
123         )
124         .expect("reading file"),
125         buffer.len(),
126         "should read {} bytes",
127         buffer.len()
128     );
129 
130     assert_eq!(&data[..], &buffer[..]);
131 
132     wasip1::fd_close(file_fd).expect("close file");
133 
134     let stat = wasip1::path_filestat_get(dir_fd, 0, FILE_NAME).expect("stat path");
135 
136     assert_eq!(stat.size, 200, "expected a file size of 200");
137 
138     wasip1::path_unlink_file(dir_fd, FILE_NAME).expect("unlinking file");
139 }
140 
main()141 fn main() {
142     let mut args = env::args();
143     let prog = args.next().unwrap();
144     let arg = if let Some(arg) = args.next() {
145         arg
146     } else {
147         eprintln!("usage: {prog} <scratch directory>");
148         process::exit(1);
149     };
150 
151     let dir_fd = match open_scratch_directory(&arg) {
152         Ok(dir_fd) => dir_fd,
153         Err(err) => {
154             eprintln!("{err}");
155             process::exit(1)
156         }
157     };
158 
159     unsafe {
160         test_fd_fdstat_set_flags(dir_fd);
161     }
162 }
163