1 use wasip2::filesystem::types::*; 2 use wasip2::sockets::network::*; 3 4 fn main() { 5 match std::env::args().nth(1).as_deref() { 6 Some("poll") => poll(), 7 Some("read") => read(), 8 Some("write") => write(), 9 Some("write-stream") => write_stream(), 10 Some("write-stream-blocking") => write_stream_blocking(), 11 Some("mkdir") => mkdir(), 12 Some("resolve") => resolve(), 13 Some("udp-send-many") => udp_send_many(), 14 Some("udp-send-big") => udp_send_big(), 15 Some("write-zeroes") => write_zeroes(), 16 Some("write-stream-buffer-too-large") => write_stream_buffer_too_large(), 17 Some("write-zeroes-buffer-too-large") => write_zeroes_buffer_too_large(), 18 Some("read-file-big") => read_file_big(), 19 Some("read-tcp-big") => read_tcp_big(), 20 other => panic!("unknown arg {other:?}"), 21 } 22 } 23 24 fn poll() { 25 let mut events = Vec::new(); 26 let sub = wasip2::clocks::monotonic_clock::subscribe_duration(0); 27 for _ in 0..5000 { 28 events.push(&sub); 29 } 30 31 wasip2::io::poll::poll(&events); 32 unreachable!() 33 } 34 35 fn preopen() -> Descriptor { 36 let mut dirs = wasip2::filesystem::preopens::get_directories(); 37 assert_eq!(dirs.len(), 1); 38 dirs.pop().unwrap().0 39 } 40 41 fn read() { 42 let f = preopen() 43 .open_at( 44 PathFlags::empty(), 45 "1mb", 46 OpenFlags::empty(), 47 DescriptorFlags::empty(), 48 ) 49 .unwrap(); 50 51 // 0-length is ok 52 f.read(0, 0).unwrap(); 53 54 // This isn't transferring data from the guest to the host, so this is ok. 55 f.read(1 << 20, 0).unwrap(); 56 57 // Host shouldn't allocate based on what the guest asks for... 58 f.read(u64::MAX, 0).unwrap(); 59 60 f.read_via_stream(0) 61 .unwrap() 62 .blocking_read(1 << 20) 63 .unwrap(); 64 } 65 66 fn write() { 67 let f = preopen() 68 .open_at( 69 PathFlags::empty(), 70 "hi", 71 OpenFlags::CREATE, 72 DescriptorFlags::empty(), 73 ) 74 .unwrap(); 75 f.write(&[0; 5001], 0).unwrap(); 76 unreachable!() 77 } 78 79 fn write_stream() { 80 preopen() 81 .open_at( 82 PathFlags::empty(), 83 "hi", 84 OpenFlags::CREATE, 85 DescriptorFlags::empty(), 86 ) 87 .unwrap() 88 .write_via_stream(0) 89 .unwrap() 90 .write(&[0; 5001]) 91 .unwrap(); 92 unreachable!() 93 } 94 95 fn write_stream_blocking() { 96 preopen() 97 .open_at( 98 PathFlags::empty(), 99 "hi", 100 OpenFlags::CREATE, 101 DescriptorFlags::empty(), 102 ) 103 .unwrap() 104 .write_via_stream(0) 105 .unwrap() 106 .blocking_write_and_flush(&[0; 5001]) 107 .unwrap(); 108 unreachable!() 109 } 110 111 fn mkdir() { 112 let mut name = String::new(); 113 for _ in 0..5001 { 114 name.push_str("a"); 115 } 116 preopen().create_directory_at(&name).unwrap(); 117 unreachable!() 118 } 119 120 fn resolve() { 121 let network = wasip2::sockets::instance_network::instance_network(); 122 let mut name = String::new(); 123 for _ in 0..5001 { 124 name.push_str("a"); 125 } 126 wasip2::sockets::ip_name_lookup::resolve_addresses(&network, &name).unwrap(); 127 unreachable!(); 128 } 129 130 fn udp_socket() -> wasip2::sockets::udp::UdpSocket { 131 let socket = 132 wasip2::sockets::udp_create_socket::create_udp_socket(IpAddressFamily::Ipv4).unwrap(); 133 let network = wasip2::sockets::instance_network::instance_network(); 134 135 socket 136 .start_bind( 137 &network, 138 IpSocketAddress::Ipv4(Ipv4SocketAddress { 139 address: (127, 0, 0, 1), 140 port: 0, 141 }), 142 ) 143 .unwrap(); 144 socket.finish_bind().unwrap(); 145 socket 146 } 147 148 fn udp_send_many() { 149 let socket = udp_socket(); 150 let (_incoming, outgoing) = socket.stream(None).unwrap(); 151 let mut dgrams = Vec::new(); 152 153 for _ in 0..5000 { 154 dgrams.push(wasip2::sockets::udp::OutgoingDatagram { 155 data: Vec::new(), 156 remote_address: None, 157 }); 158 } 159 160 outgoing.send(&dgrams).unwrap(); 161 unreachable!() 162 } 163 164 fn udp_send_big() { 165 let socket = udp_socket(); 166 let (_incoming, outgoing) = socket.stream(None).unwrap(); 167 let mut dgrams = Vec::new(); 168 169 for _ in 0..2 { 170 dgrams.push(wasip2::sockets::udp::OutgoingDatagram { 171 data: vec![0; 2500], 172 remote_address: None, 173 }); 174 } 175 176 outgoing.send(&dgrams).unwrap(); 177 unreachable!() 178 } 179 180 fn write_zeroes() { 181 preopen() 182 .open_at( 183 PathFlags::empty(), 184 "hi", 185 OpenFlags::CREATE, 186 DescriptorFlags::empty(), 187 ) 188 .unwrap() 189 .write_via_stream(0) 190 .unwrap() 191 .write_zeroes(u64::MAX) 192 .unwrap(); 193 unreachable!() 194 } 195 196 fn write_stream_buffer_too_large() { 197 preopen() 198 .open_at( 199 PathFlags::empty(), 200 "hi", 201 OpenFlags::CREATE, 202 DescriptorFlags::empty(), 203 ) 204 .unwrap() 205 .write_via_stream(0) 206 .unwrap() 207 .blocking_write_and_flush(&[0; 5000]) 208 .unwrap(); 209 unreachable!() 210 } 211 212 fn write_zeroes_buffer_too_large() { 213 preopen() 214 .open_at( 215 PathFlags::empty(), 216 "hi", 217 OpenFlags::CREATE, 218 DescriptorFlags::empty(), 219 ) 220 .unwrap() 221 .write_via_stream(0) 222 .unwrap() 223 .blocking_write_zeroes_and_flush(5000) 224 .unwrap(); 225 unreachable!() 226 } 227 228 fn read_file_big() { 229 preopen() 230 .open_at( 231 PathFlags::empty(), 232 "1mb", 233 OpenFlags::empty(), 234 DescriptorFlags::empty(), 235 ) 236 .unwrap() 237 .read_via_stream(0) 238 .unwrap() 239 .blocking_read(u64::MAX) 240 .unwrap(); 241 } 242 243 fn read_tcp_big() { 244 let server = 245 wasip2::sockets::tcp_create_socket::create_tcp_socket(IpAddressFamily::Ipv4).unwrap(); 246 let client = 247 wasip2::sockets::tcp_create_socket::create_tcp_socket(IpAddressFamily::Ipv4).unwrap(); 248 249 server 250 .start_bind( 251 &wasip2::sockets::instance_network::instance_network(), 252 IpSocketAddress::Ipv4(Ipv4SocketAddress { 253 address: (127, 0, 0, 1), 254 port: 0, 255 }), 256 ) 257 .unwrap(); 258 server.finish_bind().unwrap(); 259 server.start_listen().unwrap(); 260 server.finish_listen().unwrap(); 261 262 client 263 .start_connect( 264 &wasip2::sockets::instance_network::instance_network(), 265 server.local_address().unwrap(), 266 ) 267 .unwrap(); 268 client.subscribe().block(); 269 let (input, _output) = client.finish_connect().unwrap(); 270 271 { 272 server.subscribe().block(); 273 let (socket, input, output) = server.accept().unwrap(); 274 drop((input, output)); 275 drop(socket); 276 } 277 278 match input.blocking_read(u64::MAX) { 279 Err(wasip2::io::streams::StreamError::Closed) => {} 280 other => panic!("unexpected result: {other:?}"), 281 } 282 } 283