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