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 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 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