diff --git a/imports/wasi_snapshot_preview1/testdata/cargo-wasi/Cargo.toml b/imports/wasi_snapshot_preview1/testdata/cargo-wasi/Cargo.toml index f1e93d7b4e5..8282d207977 100644 --- a/imports/wasi_snapshot_preview1/testdata/cargo-wasi/Cargo.toml +++ b/imports/wasi_snapshot_preview1/testdata/cargo-wasi/Cargo.toml @@ -9,3 +9,4 @@ path = "wasi.rs" [dependencies] libc = "0.2" +mio = {version="0.8", features=["os-poll", "net"]} diff --git a/imports/wasi_snapshot_preview1/testdata/cargo-wasi/wasi.rs b/imports/wasi_snapshot_preview1/testdata/cargo-wasi/wasi.rs index 3641e539492..d0345483cad 100644 --- a/imports/wasi_snapshot_preview1/testdata/cargo-wasi/wasi.rs +++ b/imports/wasi_snapshot_preview1/testdata/cargo-wasi/wasi.rs @@ -6,6 +6,10 @@ use std::net::{TcpListener}; use std::os::wasi::io::FromRawFd; use std::process::exit; use std::str::from_utf8; +use std::error::Error; + +use std::collections::HashMap; +use std::time::Duration; // Until NotADirectory is implemented, read the underlying error raised by // wasi-libc. See https://github.com/rust-lang/rust/issues/86442 @@ -23,6 +27,7 @@ fn main() { } "stat" => main_stat(), "sock" => main_sock(), + "mixed" => main_mixed().unwrap(), _ => { writeln!(io::stderr(), "unknown command: {}", args[1]).unwrap(); exit(1); @@ -87,3 +92,103 @@ fn main_sock() { } } } + +fn main_mixed() -> Result<(), Box> { + + use mio::net::{TcpListener, TcpStream}; + use mio::{Events, Interest, Poll, Token}; + + // Some tokens to allow us to identify which event is for which socket. + const SERVER: Token = Token(0); + const STDIN: Token = Token(1); + + // Create a poll instance. + let mut poll = Poll::new()?; + // Create storage for events. + let mut events = Events::with_capacity(128); + + let mut server = unsafe { TcpListener::from_raw_fd(3) }; + let mut stdin = unsafe { TcpStream::from_raw_fd(0) }; + + + // Start listening for incoming connections. + poll.registry() + .register(&mut server, SERVER, Interest::READABLE)?; + + // Keep track of incoming connections. + let mut m: HashMap = HashMap::new(); + + let mut count = 2; + + // Start an event loop. + loop { + // Poll Mio for events, blocking until we get an event. + if let Err(e) = poll.poll(&mut events, Some(Duration::from_nanos(0))) { + // Ignore EINTR. + if e.kind() == std::io::ErrorKind::Interrupted { + continue; + } + return Err(Box::from(e)) + } + + // Process each event. + for event in events.iter() { + // We can use the token we previously provided to `register` to + // determine for which socket the event is. + match event.token() { + SERVER => { + // If this is an event for the server, it means a connection + // is ready to be accepted. + // + // Accept the connection and add it to the map. + match server.accept() { + Ok((mut connection, _addr)) => { + let tok = Token(count); + _ = poll.registry() + .register(&mut connection, tok, Interest::READABLE); + m.insert(tok, connection); + // drop(connection); + count+=1; + }, + Err(e) if e.kind() == std::io::ErrorKind::WouldBlock => { + // ignore + }, + Err(err) => panic!("ERROR! {}", err), + } + }, + + STDIN => { + // There is for reading on one of our connections, read it and echo. + let mut buf = [0u8; 32]; + match stdin.read(&mut buf) { + Ok(n) if n>0 => + println!("{}", String::from_utf8_lossy(&buf[0..n])), + _ => {} // ignore error. + } + }, + + + conn_id => { + // There is for reading on one of our connections, read it and echo. + let mut buf = [0u8; 32]; + let mut el = m.get(&conn_id).unwrap(); + match el.read(&mut buf) { + Ok(n) if n>0 => { + let s = String::from_utf8_lossy(&buf[0..n]); + println!("{}", s); + // Quit when the socket contains the string wazero. + if s.contains("wazero") { + return Ok(()); + } + }, + + _ => {} // ignore error. + } + } + } + } + + } +} + + diff --git a/imports/wasi_snapshot_preview1/testdata/cargo-wasi/wasi.wasm b/imports/wasi_snapshot_preview1/testdata/cargo-wasi/wasi.wasm index 2ddde1064d2..8cafb21ed2e 100644 Binary files a/imports/wasi_snapshot_preview1/testdata/cargo-wasi/wasi.wasm and b/imports/wasi_snapshot_preview1/testdata/cargo-wasi/wasi.wasm differ diff --git a/imports/wasi_snapshot_preview1/wasi_stdlib_test.go b/imports/wasi_snapshot_preview1/wasi_stdlib_test.go index f29c2e1f4d0..9007ff24343 100644 --- a/imports/wasi_snapshot_preview1/wasi_stdlib_test.go +++ b/imports/wasi_snapshot_preview1/wasi_stdlib_test.go @@ -640,8 +640,8 @@ func testLargeStdout(t *testing.T, tname string, bin []byte) { func Test_Mixed(t *testing.T) { toolchains := map[string][]byte{ - // TODO: "cargo-wasi": wasmCargoWasi, - "zig-cc": wasmZigCc, + "cargo-wasi": wasmCargoWasi, + "zig-cc": wasmZigCc, } if wasmGotip != nil { toolchains["gotip"] = wasmGotip