diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d6cc286a..2d422925 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -8,6 +8,7 @@ jobs: strategy: matrix: output: + - chat-client-rust-tokio - chat-server-rust-tokio - cryptle-rust - echo-tcp-rust-mio diff --git a/Rust/tokio-chat-client/.cargo/config b/Rust/tokio-chat-client/.cargo/config new file mode 100644 index 00000000..b105d9cf --- /dev/null +++ b/Rust/tokio-chat-client/.cargo/config @@ -0,0 +1,6 @@ +[build] +target = "wasm32-wasi" + +[target.wasm32-wasi] +runner = ["enarx", "run", "--wasmcfgfile", "Enarx.toml"] +rustflags = [ "--cfg", "tokio_unstable"] diff --git a/Rust/tokio-chat-client/Cargo.lock b/Rust/tokio-chat-client/Cargo.lock new file mode 100644 index 00000000..3c26279f --- /dev/null +++ b/Rust/tokio-chat-client/Cargo.lock @@ -0,0 +1,396 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "anyhow" +version = "1.0.63" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a26fa4d7e3f2eebadf743988fc8aec9fa9a9e82611acafd77c1462ed6262440a" + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + +[[package]] +name = "bytes" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "206fdffcfa2df7cbe15601ef46c813fce0965eb3286db6b56c583b814b51c81c" +dependencies = [ + "byteorder", + "iovec", +] + +[[package]] +name = "bytes" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec8a7b6a70fde80372154c65702f00a0f56f3e1c36abbc6c440484be248856db" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "futures" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a471a38ef8ed83cd6e40aa59c1ffe17db6855c18e3604d9c4ed8c08ebc28678" + +[[package]] +name = "futures" +version = "0.3.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f21eda599937fba36daeb58a22e8f5cee2d14c4a17b5b7739c7c8e5e3b8230c" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30bdd20c28fadd505d0fd6712cdfcb0d4b5648baf45faef7f852afb2399bb050" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e5aa3de05362c3fb88de6531e6296e85cde7739cccad4b9dfeeb7f6ebce56bf" + +[[package]] +name = "futures-executor" +version = "0.3.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ff63c23854bee61b6e9cd331d523909f238fc7636290b96826e9cfa5faa00ab" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbf4d2a7a308fd4578637c0b17c7e1c7ba127b8f6ba00b29f717e9655d85eb68" + +[[package]] +name = "futures-macro" +version = "0.3.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42cd15d1c7456c04dbdf7e88bcd69760d74f3a798d6444e16974b505b0e62f17" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "futures-sink" +version = "0.3.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21b20ba5a92e727ba30e72834706623d94ac93a725410b6a6b6fbc1b07f7ba56" + +[[package]] +name = "futures-task" +version = "0.3.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6508c467c73851293f390476d4491cf4d227dbabcd4170f3bb6044959b294f1" + +[[package]] +name = "futures-util" +version = "0.3.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44fb6cb1be61cc1d2e43b262516aafcf63b241cffdb1d3fa115f91d9c7b09c90" +dependencies = [ + "futures 0.1.31", + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", + "tokio-io", +] + +[[package]] +name = "iovec" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" +dependencies = [ + "libc", +] + +[[package]] +name = "libc" +version = "0.2.132" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8371e4e5341c3a96db127eb2465ac681ced4c433e01dd0e938adbef26ba93ba5" + +[[package]] +name = "log" +version = "0.4.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "memchr" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" + +[[package]] +name = "mio" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57ee1c23c7c63b0c9250c339ffdc69255f110b298b901b9f6c82547b7b87caaf" +dependencies = [ + "libc", + "log", + "wasi", + "windows-sys", +] + +[[package]] +name = "once_cell" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "074864da206b4973b84eb91683020dbefd6a8c3f0f38e054d93954e891935e4e" + +[[package]] +name = "pin-project-lite" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "proc-macro2" +version = "1.0.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a2ca2c61bc9f3d74d2886294ab7b9853abd9c1ad903a3ac7815c58989bb7bab" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "slab" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef" +dependencies = [ + "autocfg", +] + +[[package]] +name = "socket2" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02e2d2db9033d13a1567121ddd7a095ee144db4e1ca1b1bda3419bc0da294ebd" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "syn" +version = "1.0.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58dbef6ec655055e20b86b15a8cc6d439cca19b667537ac6a1369572d151ab13" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "tokio" +version = "1.20.0" +source = "git+https://github.com/tokio-rs/tokio?rev=56be5286ee9548c483b91b7593ededcd34c5da0b#56be5286ee9548c483b91b7593ededcd34c5da0b" +dependencies = [ + "autocfg", + "bytes 1.2.1", + "libc", + "memchr", + "mio", + "once_cell", + "pin-project-lite", + "socket2", + "tokio-macros", + "winapi", +] + +[[package]] +name = "tokio-chat-client" +version = "0.1.0" +dependencies = [ + "anyhow", + "futures 0.3.24", + "tokio", + "tokio-stream", +] + +[[package]] +name = "tokio-io" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57fc868aae093479e3131e3d165c93b1c7474109d13c90ec0dda2a1bbfff0674" +dependencies = [ + "bytes 0.4.12", + "futures 0.1.31", + "log", +] + +[[package]] +name = "tokio-macros" +version = "1.8.0" +source = "git+https://github.com/tokio-rs/tokio?rev=56be5286ee9548c483b91b7593ededcd34c5da0b#56be5286ee9548c483b91b7593ededcd34c5da0b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tokio-stream" +version = "0.1.9" +source = "git+https://github.com/tokio-rs/tokio?rev=56be5286ee9548c483b91b7593ededcd34c5da0b#56be5286ee9548c483b91b7593ededcd34c5da0b" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", + "tokio-util", +] + +[[package]] +name = "tokio-util" +version = "0.7.3" +source = "git+https://github.com/tokio-rs/tokio?rev=56be5286ee9548c483b91b7593ededcd34c5da0b#56be5286ee9548c483b91b7593ededcd34c5da0b" +dependencies = [ + "bytes 1.2.1", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "unicode-ident" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4f5b37a154999a8f3f98cc23a628d850e154479cd94decf3414696e12e31aaf" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-sys" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" +dependencies = [ + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" + +[[package]] +name = "windows_i686_gnu" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" + +[[package]] +name = "windows_i686_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" diff --git a/Rust/tokio-chat-client/Cargo.toml b/Rust/tokio-chat-client/Cargo.toml new file mode 100644 index 00000000..70561deb --- /dev/null +++ b/Rust/tokio-chat-client/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "tokio-chat-client" +version = "0.1.0" +edition = "2021" +publish = false + +[dependencies] +anyhow = "1.0.57" +futures = { version = "0.3.24", features = ["io-compat"] } +tokio = { git = "https://github.com/tokio-rs/tokio", rev = "56be5286ee9548c483b91b7593ededcd34c5da0b", default-features = false, features = ["fs", "net", "rt", "macros", "io-util", "io-std"] } +tokio-stream = { git = "https://github.com/tokio-rs/tokio", rev = "56be5286ee9548c483b91b7593ededcd34c5da0b", default-features = false, features = ["net", "io-util", "sync"] } diff --git a/Rust/tokio-chat-client/Enarx.toml b/Rust/tokio-chat-client/Enarx.toml new file mode 100644 index 00000000..62034b3e --- /dev/null +++ b/Rust/tokio-chat-client/Enarx.toml @@ -0,0 +1,15 @@ +[[files]] +kind = "stdin" + +[[files]] +kind = "stdout" + +[[files]] +kind = "stderr" + +[[files]] +name = "server" +kind = "connect" +port = 50000 +prot = "tcp" +host = "127.0.0.1" diff --git a/Rust/tokio-chat-client/src/main.rs b/Rust/tokio-chat-client/src/main.rs new file mode 100644 index 00000000..2c71becb --- /dev/null +++ b/Rust/tokio-chat-client/src/main.rs @@ -0,0 +1,58 @@ +use std::env; +#[cfg(unix)] +use std::os::unix::io::FromRawFd; +#[cfg(target_os = "wasi")] +use std::os::wasi::io::FromRawFd; +use std::str::FromStr; + +use anyhow::{bail, Context}; +use futures::StreamExt; +use tokio::io::{AsyncBufReadExt, AsyncWriteExt, BufReader}; +use tokio::net::TcpStream; +use tokio_stream::wrappers::LinesStream; + +#[tokio::main(flavor = "current_thread")] +async fn main() -> anyhow::Result<()> { + let fd_count = env::var("FD_COUNT").context("failed to lookup `FD_COUNT`")?; + let fd_count = usize::from_str(&fd_count).context("failed to parse `FD_COUNT`")?; + assert_eq!( + fd_count, + 4, // STDIN, STDOUT, STDERR and a socket + "unexpected amount of file descriptors received" + ); + let mut stream = match env::var("FD_NAMES") + .context("failed to lookup `FD_NAMES`")? + .splitn(fd_count, ':') + .nth(3) + { + None => bail!("failed to parse `FD_NAMES`"), + Some("server") => { + let s = unsafe { std::net::TcpStream::from_raw_fd(3) }; + s.set_nonblocking(true) + .context("failed to set non-blocking flag on ingest socket")?; + TcpStream::from_std(s).context("failed to initialize Tokio stream")? + } + Some(name) => bail!("unknown socket name `{name}`"), + }; + + // TODO: Send and receive multiple messages concurrently once async reads from stdin are possible + for line in std::io::stdin().lines() { + let line = line.context("failed to read line from STDIN")?; + stream + .write_all(format!("{line}\n").as_bytes()) + .await + .context("failed to send line")?; + } + + LinesStream::new(BufReader::new(stream).lines()) + .fuse() + .for_each(|line| async { + match line { + Err(e) => eprintln!("* failed to receive line: {e}"), + Ok(line) => println!("{line}"), + } + }) + .await; + + Ok(()) +} diff --git a/flake.nix b/flake.nix index f43591e7..19027fa4 100644 --- a/flake.nix +++ b/flake.nix @@ -72,6 +72,19 @@ rustc = rust; }; in { + chat-client-rust-tokio-wasm = naersk-lib.buildPackage { + src = "${self}/Rust/tokio-chat-client"; + CARGO_BUILD_TARGET = "wasm32-wasi"; + }; + + chat-client-rust-tokio = buildEnarxPackage { + inherit (final) pkgs; + inherit (cargoPackage "${self}/Rust/tokio-chat-client/Cargo.toml") name version; + + wasm = "${final.chat-client-rust-tokio-wasm}/bin/tokio-chat-client.wasm"; + conf = "${self}/Rust/tokio-chat-client/Enarx.toml"; + }; + chat-server-rust-tokio-wasm = naersk-lib.buildPackage { src = "${self}/Rust/tokio-chat-server"; CARGO_BUILD_TARGET = "wasm32-wasi"; @@ -289,6 +302,8 @@ packages = with pkgs; { inherit + chat-client-rust-tokio + chat-client-rust-tokio-wasm chat-server-rust-tokio chat-server-rust-tokio-wasm echo-tcp-rust-mio