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` package
Your 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
PATH
environment variable to/bin
. This is required because thels
command is located in/bin
directory. - 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-opt
Yay, 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