Documentation
Language Guide
C
Tutorials
Spawn

Spawing Processes with WASIX

This sample project demonstrates how to spawn a child process with 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 tools to be installed on your system:

Start a new project

Create a new directory for your project

$ mkdir wasix-spawn
$ cd wasix-spawn

Make a new file called spawn.c

$ touch spawn.c

Link the SysRoot

ℹ️

You need to link the SysRoot to your project. The SysRoot is a directory that contains the WASI libc headers and libraries. The SysRoot is located in the Wasix-libc binary or you can compile it yourself.

Writing the Application

Basic Application Setup

We want to write a program that demonstrates how to use the posix_spawn function to spawn a child process that runs the echo command with the arguments "hi" and NULL. The parent process should wait for the child to exit and then print the exit status.

Let's write code for the above:

spawn.c
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <spawn.h>
#include <sys/wait.h>
 
extern char **environ; // environment variables
 
/**
 * This program uses posix_spawn to spawn a child process that runs the
 * echo command with the arguments "hi" and NULL. The parent process should
 * wait for the child to exit and then print the exit status.
 */
int main(int argc, char *argv[])
{
 
    pid_t pid;                                                                // The pid of the child process will be stored here
    char *child_argv[] = {"echo", "hi", NULL};                                // The arguments to the child process
    int status;                                                               // The exit status of the child process will be stored here
    status = posix_spawn(&pid, "/bin/echo", NULL, NULL, child_argv, environ); // Spawn the child process
 
    /**
     * If the child process was successfully spawned, wait for it to exit and
     */
    if (status == 0)
    {
        printf("Child pid: %i\n", pid); // Print the pid of the child process
 
        /**
         * Wait for the child process to exit and print the exit status
         */
        do
        {
            if (waitpid(pid, &status, 0) != -1)
            {
                printf("Child status %d\n", WEXITSTATUS(status));
            }
            else
            {
                perror("waitpid");
                exit(1);
            }
        } while (!WIFEXITED(status) && !WIFSIGNALED(status));
    }
    /**
     * If the child process was not successfully spawned, print the error
     * message
     */
    else
    {
        printf("posix_spawn: %s\n", strerror(status));
    }
    return 0;
}

Compiling the Application

Let's compile the application with clang:

$ clang -o spawn spawn.c

Running the Application

We can run the application with the following command:

$ ./spawn
Child pid: 42287
hi
Child status 0

We see that the child process was successfully spawned and exited with status 0.

Let's try to build this example with WASIX.

$ /path/to/wasix-sdk/clang spawn.c --target="wasm32-wasi" -o spawn.wasm

It's compiling! Now, let's try to run it:

🗂️

To give the applications a context of spawned processes in the WASIX environment we need to include coreutils. We can do that by passing the module to the wasmer run command using the --use flag and passing the "sharrattj/coreutils"` module.

$ wasmer run spawn.wasm --use sharrattj/coreutils
Child pid: 2
Hello
Child status 0

It works!

Conclusion

In this tutorial we learned:

  • How to spawn a child process with WASIX in C
  • Compiling a C program with WASIX
  • How to use the --use flag to include modules in the WASIX environment
wasix-libc/examples/spawn.c