liveBook · Manning

Signal handler

As explained in Rust in Action: Systems programming concepts and techniques

A signal handler is a function or disposition associated with a signal that determines how a process responds when the signal is delivered.

A signal handler determines what a process does when a signal arrives. Without a custom handler, many signals terminate the process. A custom handler can instead give an application a chance to shut down cleanly—for example, by closing network connections or finishing pending writes. section 12.5.1 section 12.6

Keep the handler quick and simple. It receives the signal number, but not the application state needed for cleanup. It can also block another signal of the same type while it runs. A practical pattern is to have the handler set a global Boolean flag; the main loop checks that flag and performs cleanup in its normal context. section 12.6 section 12.12

To wire up that pattern in Rust:

  • Define a handler with the signature fn(i32) -> (): it takes the signal number and returns nothing. section 12.6
  • Register it with libc::signal() for the signal you want to handle. Do this early, before the main loop starts. section 12.6.2
  • Use a mutable static for the shared shutdown flag, and access it within unsafe blocks. Let the main loop respond when it sees the flag. section 12.12 section 12.6.2

Responding to SIGTERM

A small program registers handlers, prints its progress in a loop, and raises signals to test them. Its SIGTERM handler changes a global shutdown flag. On the next loop check, the program sees the flag and exits through its own code rather than relying on SIGTERM’s default termination. section 12.6.2

Listing 12.12 Ignoring signals with libc::SIG_IGN
 1 use libc::{signal,raise};
 2 use libc::{SIG_DFL, SIG_IGN, SIGTERM};
 3  
 4 fn main() {
 5   unsafe {                        #1
 6     signal(SIGTERM, SIG_IGN);     #2
 7     raise(SIGTERM);               #3
 8   }
 9  
10   println!("ok");
11  
12   unsafe {
13     signal(SIGTERM, SIG_DFL);     #4
14     raise(SIGTERM);               #5
15   }
16  
17   println!("not ok");             #6
18 }

A handler need not be a function: this listing passes SIG_IGN to libc::signal() to ignore SIGTERM, then passes SIG_DFL to restore its default behavior. SIGSTOP and SIGKILL cannot be ignored this way. section 12.8

How Rust in Action: Systems programming concepts and techniques covers it

How deep it goes
Works through registration, handler constraints, and a main-loop flag pattern without developing a general signal-handling reference.
Examples
Tests SIGTERM and SIGUSR1 in a looping program and demonstrates ignoring SIGTERM before restoring its default behavior.
What it assumes
Builds on Rust functions and loops while explaining the handler signature, function pointers, and mutable-static access.
What you can do after
Apply it via Rust’s libc::signal() to register a minimal handler and let the main loop initiate shutdown.
How it connects
Connects signal handlers to function pointers, mutable statics, unsafe access, and process shutdown.

Also explained in

Compare how 4 books explain signal handler →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Rust in Action: Systems programming concepts and techniques. The section links point to the parts of the book it draws on.