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::{assert_errno, create_file, open_scratch_directory};
5
test_path_open_read_write(dir_fd: wasip1::Fd)6 unsafe fn test_path_open_read_write(dir_fd: wasip1::Fd) {
7 create_file(dir_fd, "file");
8
9 let f_readonly = wasip1::path_open(dir_fd, 0, "file", 0, wasip1::RIGHTS_FD_READ, 0, 0)
10 .expect("open file readonly");
11
12 let stat = wasip1::fd_fdstat_get(f_readonly).expect("get fdstat readonly");
13 assert!(
14 stat.fs_rights_base & wasip1::RIGHTS_FD_READ == wasip1::RIGHTS_FD_READ,
15 "readonly has read right"
16 );
17 assert!(
18 stat.fs_rights_base & wasip1::RIGHTS_FD_WRITE == 0,
19 "readonly does not have write right"
20 );
21
22 let buffer = &mut [0u8; 100];
23 let iovec = wasip1::Iovec {
24 buf: buffer.as_mut_ptr(),
25 buf_len: buffer.len(),
26 };
27 let nread = wasip1::fd_read(f_readonly, &[iovec]).expect("reading readonly file");
28 assert_eq!(nread, 0, "readonly file is empty");
29
30 let write_buffer = &[1u8; 50];
31 let ciovec = wasip1::Ciovec {
32 buf: write_buffer.as_ptr(),
33 buf_len: write_buffer.len(),
34 };
35 // PERM is only the failure on windows under wasmtime-wasi. wasi-common
36 // fails on windows with BADF, so we can't use the `windows =>` syntax
37 // because that doesn't support alternatives like the agnostic syntax does.
38 assert_errno!(
39 wasip1::fd_write(f_readonly, &[ciovec])
40 .err()
41 .expect("read of writeonly fails"),
42 wasip1::ERRNO_PERM,
43 wasip1::ERRNO_BADF
44 );
45
46 wasip1::fd_close(f_readonly).expect("close readonly");
47
48 // =============== WRITE ONLY ==================
49 let f_writeonly = wasip1::path_open(dir_fd, 0, "file", 0, wasip1::RIGHTS_FD_WRITE, 0, 0)
50 .expect("open file writeonly");
51
52 let stat = wasip1::fd_fdstat_get(f_writeonly).expect("get fdstat writeonly");
53 assert!(
54 stat.fs_rights_base & wasip1::RIGHTS_FD_READ == 0,
55 "writeonly does not have read right"
56 );
57 assert!(
58 stat.fs_rights_base & wasip1::RIGHTS_FD_READDIR == 0,
59 "writeonly does not have readdir right"
60 );
61 assert!(
62 stat.fs_rights_base & wasip1::RIGHTS_FD_WRITE == wasip1::RIGHTS_FD_WRITE,
63 "writeonly has write right"
64 );
65
66 // See above for description of PERM
67 assert_errno!(
68 wasip1::fd_read(f_writeonly, &[iovec])
69 .err()
70 .expect("read of writeonly fails"),
71 wasip1::ERRNO_PERM,
72 wasip1::ERRNO_BADF
73 );
74 let bytes_written = wasip1::fd_write(f_writeonly, &[ciovec]).expect("write to writeonly");
75 assert_eq!(bytes_written, write_buffer.len());
76
77 wasip1::fd_close(f_writeonly).expect("close writeonly");
78
79 // ============== READ WRITE =======================
80
81 let f_readwrite = wasip1::path_open(
82 dir_fd,
83 0,
84 "file",
85 0,
86 wasip1::RIGHTS_FD_READ | wasip1::RIGHTS_FD_WRITE,
87 0,
88 0,
89 )
90 .expect("open file readwrite");
91 let stat = wasip1::fd_fdstat_get(f_readwrite).expect("get fdstat readwrite");
92 assert!(
93 stat.fs_rights_base & wasip1::RIGHTS_FD_READ == wasip1::RIGHTS_FD_READ,
94 "readwrite has read right"
95 );
96 assert!(
97 stat.fs_rights_base & wasip1::RIGHTS_FD_WRITE == wasip1::RIGHTS_FD_WRITE,
98 "readwrite has write right"
99 );
100
101 let nread = wasip1::fd_read(f_readwrite, &[iovec]).expect("reading readwrite file");
102 assert_eq!(
103 nread,
104 write_buffer.len(),
105 "readwrite file contains contents from writeonly open"
106 );
107
108 let write_buffer_2 = &[2u8; 25];
109 let ciovec = wasip1::Ciovec {
110 buf: write_buffer_2.as_ptr(),
111 buf_len: write_buffer_2.len(),
112 };
113 let bytes_written = wasip1::fd_write(f_readwrite, &[ciovec]).expect("write to readwrite");
114 assert_eq!(bytes_written, write_buffer_2.len());
115
116 let filestat = wasip1::fd_filestat_get(f_readwrite).expect("get filestat readwrite");
117 assert_eq!(
118 filestat.size as usize,
119 write_buffer.len() + write_buffer_2.len(),
120 "total written is both write buffers"
121 );
122
123 wasip1::fd_close(f_readwrite).expect("close readwrite");
124
125 wasip1::path_unlink_file(dir_fd, "file").expect("removing a file");
126 }
127
main()128 fn main() {
129 let mut args = env::args();
130 let prog = args.next().unwrap();
131 let arg = if let Some(arg) = args.next() {
132 arg
133 } else {
134 eprintln!("usage: {prog} <scratch directory>");
135 process::exit(1);
136 };
137
138 // Open scratch directory
139 let dir_fd = match open_scratch_directory(&arg) {
140 Ok(dir_fd) => dir_fd,
141 Err(err) => {
142 eprintln!("{err}");
143 process::exit(1)
144 }
145 };
146
147 // Run the tests.
148 unsafe { test_path_open_read_write(dir_fd) }
149 }
150