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