Documentation
Language Guide
C
Tutorials
Signal

Signals with WASIX

This sample project demonstrates how signals work 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-signal
$ cd wasix-signal

Make a new file called signal.c:

$ touch signal.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 simple C program that demonstrates how to handle signals in a process. It should set up signal handlers for two signals: SIGHUP and SIGINT.

Let's write code for the above:

signal.c
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
 
volatile int run = 1; // set to 0 when SIGINT is caught
 
/*
 * Signal handler function.
 * It is called when a signal is delivered to the process.
 */
void sig_handler(int signo)
{
    // SIGHUP is sent when user closes the terminal
    if (signo == SIGHUP)
    {
        run = 0; // set to 0 to terminate the program
        printf("received SIGHUP\n");
    }
    // SIGINT is sent when user presses Ctrl+C
    if (signo == SIGINT)
    {
        run = 0; // set to 0 to terminate the program
        printf("received SIGINT\n");
    }
}
 
int main(void)
{
    if (signal(SIGINT, sig_handler) == SIG_ERR)
        printf("\ncan't catch SIGINT\n");
    if (signal(SIGHUP, sig_handler) == SIG_ERR)
        printf("\ncan't catch SIGHUP\n");
 
    /*
     * Raise a SIGHUP signal.
     */
    raise(SIGHUP);
 
    // A long long wait so that we can easily issue a signal to this process
    while (run)
    {
        printf("running...\n");
        sleep(1); // sleep for 1 second
    }
 
    return 0;
}

The main function sets up the signal handlers using the signal function. It then raises a SIGHUP signal using the raise function. Finally, it enters a loop that prints "running..." every second until the run variable is set to 0 by one of the signal handlers.

Compiling the Application

Let's compile the application with clang:

$ clang -o signal signal.c

Running the Application

We can run the application with the following command:

$ ./signal
received SIGHUP

As we see the signal is received and the program terminates. But the signal is recieved so fast that we don't see the "running..." message.

Let's try to build this example with WASIX.

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

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

$ wasmer run signal.wasm
received SIGHUP

It works!

Conclusion

In this tutorial we learned:

  • How to write a simple C program that handles signals
  • Compiling a C program with WASIX
wasix-libc/examples/signal.c