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