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_file_long_write(dir_fd: wasip1::Fd, filename: &str)6 unsafe fn test_file_long_write(dir_fd: wasip1::Fd, filename: &str) {
7     // Open a file for writing
8     let file_fd = wasip1::path_open(
9         dir_fd,
10         0,
11         filename,
12         wasip1::OFLAGS_CREAT,
13         wasip1::RIGHTS_FD_WRITE,
14         0,
15         0,
16     )
17     .expect("creating a file for writing");
18 
19     let mut content = Vec::new();
20     // 16 byte string, 4096 times, is 64k
21     for n in 0..4096 {
22         let chunk = format!("123456789 {n:05} ");
23         assert_eq!(chunk.as_str().as_bytes().len(), 16);
24         content.extend_from_slice(chunk.as_str().as_bytes());
25     }
26 
27     // Write to the file
28     let nwritten = wasip1::fd_write(
29         file_fd,
30         &[wasip1::Ciovec {
31             buf: content.as_slice().as_ptr() as *const _,
32             buf_len: content.len(),
33         }],
34     )
35     .expect("writing file content");
36     assert_eq!(nwritten, content.len(), "nwritten bytes check");
37 
38     let stat = wasip1::fd_filestat_get(file_fd).expect("reading file stats");
39     assert_eq!(
40         stat.size,
41         content.len() as u64,
42         "file should be size of content",
43     );
44 
45     wasip1::fd_close(file_fd).expect("closing the file");
46     // Open the file for reading
47     let file_fd = wasip1::path_open(dir_fd, 0, filename, 0, wasip1::RIGHTS_FD_READ, 0, 0)
48         .expect("open the file for reading");
49 
50     // Read the file's contents
51     let buffer = &mut [0u8; 100];
52     let nread = wasip1::fd_read(
53         file_fd,
54         &[wasip1::Iovec {
55             buf: buffer.as_mut_ptr(),
56             buf_len: buffer.len(),
57         }],
58     )
59     .expect("reading first chunk file content");
60 
61     assert_eq!(nread, buffer.len(), "read first chunk");
62     assert_eq!(
63         buffer,
64         &content[..buffer.len()],
65         "contents of first read chunk"
66     );
67 
68     let end_cursor = content.len() - buffer.len();
69     wasip1::fd_seek(file_fd, end_cursor as i64, wasip1::WHENCE_SET)
70         .expect("seeking to end of file minus buffer size");
71 
72     let nread = wasip1::fd_read(
73         file_fd,
74         &[wasip1::Iovec {
75             buf: buffer.as_mut_ptr(),
76             buf_len: buffer.len(),
77         }],
78     )
79     .expect("reading end chunk of file content");
80 
81     assert_eq!(nread, buffer.len(), "read end chunk len");
82     assert_eq!(buffer, &content[end_cursor..], "contents of end read chunk");
83 
84     wasip1::fd_close(file_fd).expect("closing the file");
85 
86     // Open a file for writing
87     let filename = "test-zero-write-fails.txt";
88     let file_fd = wasip1::path_open(
89         dir_fd,
90         0,
91         filename,
92         wasip1::OFLAGS_CREAT,
93         wasip1::RIGHTS_FD_WRITE,
94         0,
95         0,
96     )
97     .expect("creating a file for writing");
98     wasip1::fd_close(file_fd).expect("closing the file");
99     let file_fd = wasip1::path_open(dir_fd, 0, filename, 0, wasip1::RIGHTS_FD_READ, 0, 0)
100         .expect("opening a file for writing");
101     let res = wasip1::fd_write(
102         file_fd,
103         &[wasip1::Ciovec {
104             buf: 3 as *const u8,
105             buf_len: 0,
106         }],
107     );
108     assert!(
109         res == Err(wasip1::ERRNO_BADF) || res == Err(wasip1::ERRNO_PERM),
110         "bad result {res:?}"
111     )
112 }
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_file_long_write(dir_fd, "long_write.txt") }
135 }
136