Signals in Rust

Here’s the translation of the Go code to Rust, with explanations in Markdown format suitable for Hugo:

Our first example demonstrates how to handle Unix signals in Rust. We’ll create a program that gracefully shuts down when it receives a SIGTERM or stops processing input if it receives a SIGINT. Here’s how to handle signals in Rust using channels.

use std::sync::mpsc;
use std::thread;
use signal_hook::{iterator::Signals, SIGINT, SIGTERM};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Create a channel to receive the signals
    let (tx, rx) = mpsc::channel();

    // Create a Signals instance
    let mut signals = Signals::new(&[SIGINT, SIGTERM])?;

    // Spawn a thread to handle signals
    thread::spawn(move || {
        for sig in signals.forever() {
            println!("Received signal {:?}", sig);
            tx.send(()).unwrap();
            break;
        }
    });

    println!("Awaiting signal");

    // Wait for a signal
    rx.recv().unwrap();

    println!("Exiting");
    Ok(())
}

Let’s break down the code:

  1. We use the signal_hook crate to handle Unix signals in Rust.

  2. We create a channel using mpsc::channel() to communicate between the signal handling thread and the main thread.

  3. We create a Signals instance that will listen for SIGINT and SIGTERM.

  4. We spawn a new thread that will handle the signals. When a signal is received, it prints the signal and sends a message through the channel.

  5. In the main thread, we wait for a message from the channel, which indicates that a signal has been received.

  6. Once a signal is received, the program prints “Exiting” and terminates.

To run this program, you’ll need to add the signal-hook dependency to your Cargo.toml file:

[dependencies]
signal-hook = "0.3.14"

When we run this program, it will block waiting for a signal. By typing ctrl-C (which the terminal shows as ^C), we can send a SIGINT signal, causing the program to print the received signal and then exit.

$ cargo run
   Compiling signals_example v0.1.0 (/path/to/your/project)
    Finished dev [unoptimized + debuginfo] target(s) in 1.31s
     Running `target/debug/signals_example`
Awaiting signal
^C
Received signal 2
Exiting

This example demonstrates how to handle signals in Rust, allowing for graceful shutdown or other signal-specific behavior in your applications.