Spawning a process in WASIX
This is a sample project that shows how to spawn a new process in WASIX.
Prerequisites
Please check that you have the latest version of wasmer runtime as this tutorial depends on version 4.1.1 or higher.
The project requires the following to be installed on your system:
Start a new project
$ cargo new --bin wasix-spawn
Created binary (application) `wasix-spawn` packageYour wasix-spawn directory structure should look like this:
Writing the Application
Let's write the application in src/main.rs:
use std::process::Command;
fn main() {
std::env::set_var("PATH", "/bin"); // 1.
let child = Command::new("ls") // 2.
.arg("-l")
.spawn()
.expect("Failed to spawn child process");
let result = child.wait_with_output().expect("Failed to wait on child"); // 3.
println!("status: {}", result.status); // 4.
println!("Child stdout: {}", String::from_utf8_lossy(&result.stdout)); // 4.
println!("Child stderr: {}", String::from_utf8_lossy(&result.stderr)); // 4.
}Let's go through the code above:
- We set the
PATHenvironment variable to/bin. This is required because thelscommand is located in/bindirectory. - We spawn a new process using
Command::new("ls").arg("-l").spawn(). - We wait for the child process to finish using
child.wait_with_output(). - We print the status code, stdout and stderr of the child process.
The command is located in the /bin directory because our application would
depend on sharrattj/coreutils which provides all the core utilities like
ls, cat, echo etc. and places them in the /bin directory.
Setting up our wasmer.toml
In this application, we need to setup our wasmer.toml file in order to use the sharrattj/coreutils package as a dependency.
This is required because if we compile the program directly to WASIX, it would not work as there would be no binaries available.
Let's setup our wasmer.toml file:
[package]
name = 'wasmer/wasix-spawn-example' # Replace with <your-namespace>/<your-package-name
version = '0.1.0'
description = 'An example of using spawn in wasix'
readme = 'README.md'
# See more keys and definitions at https://docs.wasmer.io/registry/manifest
[[module]]
name = 'wasix-spawn'
source = 'target/wasm32-wasmer-wasi/release/wasix-spawn.wasm'
abi = 'wasi'
[dependencies]
"sharrattj/coreutils" = "1"
[[command]]
name = 'wasix-spawn'
module = 'wasix-spawn'Running the Application
Let's compile the application to WASIX and run it:
Compiling to WASIX
$ cargo wasix build -r
Compiling wasix-spawn v0.1.0 (.../wasix-rust-examples/wasix-spawn)
Finished dev [unoptimized + debuginfo] target(s) in 0.37s
info: Post-processing WebAssembly files
Optimizing with wasm-optYay, it builds! Now, let's try to run it:
Running the Application with Wasmer
Now that we have compiled our application to WASIX, we can run it using Wasmer:
$ wasmer run target/wasm32-wasmer-wasi/release/wasix-spawn.wasm
---------- 1 somebody somegroup 0 Jan 1 1970 bin
---------- 1 somebody somegroup 0 Jan 1 1970 dev
---------- 1 somebody somegroup 0 Jan 1 1970 etc
---------- 1 somebody somegroup 0 Jan 1 1970 tmp
status: exit code: 0
Child stdout:
Child stderr:You could also run the application using wasmer run:
$ wasmer run .
---------- 1 somebody somegroup 0 Jan 1 1970 bin
---------- 1 somebody somegroup 0 Jan 1 1970 dev
---------- 1 somebody somegroup 0 Jan 1 1970 etc
---------- 1 somebody somegroup 0 Jan 1 1970 tmp
status: exit code: 0
Child stdout:
Child stderr:The above works because we have setup our wasmer.toml file with the [[command]] section.
Yay, it works! 🎉
Exercises
Exercise 1
Try to run the application with a different command.
Exercise 2
Try to take the command as an argument from the user.
$ wasmer run . -- --command="ls"You can use the -- to pass arguments to the .wasm file and use the rust's
default std::env::args to parse the arguments. Learn more about
wasmer-cli (opens in a new tab).
Conclusion
In this tutorial, we learned:
- How to spawn a new process in WASIX