[][src]Crate signal_hook

Library for easier and safe Unix signal handling

Unix signals are inherently hard to handle correctly, for several reasons:

The easy way

If you are interested in the easiest way to handle signals, head over to the Signals iterator. It is one of the abstractions provided by this library and probably the easiest one to use and with the least amount of catches.

Note that they still are some catches, most importantly that both the OS and the library may collate multiple instances of the same signal into one (if you're not consuming fast enough).

If you want an asynchronous version, see below for extension crates giving you that support.

Otherwise, read on for the full details.


This library aims to solve some of the problems. It provides a global registry of actions performed on arrival of signals. It is possible to register multiple actions for the same signal and it is possible to remove the actions later on. If there was a previous signal handler when the first action for a signal is registered, it is chained (but the original one can't be removed).

The main function of the library is register.

It also offers several common actions one might want to register, implemented in the correct way. They are scattered through submodules and have the same limitations and characteristics as the register function. Generally, they work to postpone the action taken outside of the signal handler, where the full freedom and power of rust is available.

Unlike other Rust libraries for signal handling, this should be flexible enough to handle all the common and useful patterns.

The library avoids all the newer fancy signal-handling routines. These generally have two downsides:


Even with this library, you should thread with care. It does not eliminate all the problems mentioned above.

Also, note that the OS may collate multiple instances of the same signal into just one call of the signal handler. Furthermore, some abstractions implemented here also naturally collate multiple instances of the same signal. The general guarantee is, if there was at least one signal of the given number delivered, an action will be taken, but it is not specified how many times ‒ signals work mostly as kind of „wake up now“ nudge, if the application is slow to wake up, it may be nudged multiple times before it does so.

Signal limitations

OS limits still apply ‒ it is not possible to redefine certain signals (eg. SIGKILL or SIGSTOP) and it is probably a very stupid idea to touch certain other ones (SIGSEGV, SIGFPE, SIGILL). Therefore, this library will panic if any attempt at manipulating these is made. There are some use cases for redefining the latter ones, but these are not well served by this library and you really really have to know what you're doing and are generally on your own doing that. You can, however, have a look at the very low level API in signal_hook_registry.

Signal masks

As the library uses sigaction under the hood, signal masking works as expected (eg. with pthread_sigmask). This means, signals will not be delivered if the signal is masked in all program's threads.

By the way, if you do want to modify the signal mask (or do other Unix-specific magic), the nix crate offers safe interface to many low-level functions, including pthread_sigmask.


It should work on any POSIX.1-2001 system, which are all the major big OSes with the notable exception of Windows.

Non-standard signals are also supported. Pass the signal value directly from libc or use the numeric value directly.

use std::sync::Arc;
use std::sync::atomic::{AtomicBool};
let term = Arc::new(AtomicBool::new(false));
let _ = signal_hook::flag::register(libc::SIGINT, Arc::clone(&term));

This crate includes a limited support for Windows, based on signal/raise in the CRT. There are differences in both API and behavior:

Moreover, signals won't work as you expected. SIGTERM isn't actually used and not all Ctrl-Cs are turned into SIGINT.

Patches to improve Windows support in this library are welcome.


extern crate signal_hook;

use std::io::Error;
use std::sync::Arc;
use std::sync::atomic::{AtomicBool, Ordering};

fn main() -> Result<(), Error> {
    let term = Arc::new(AtomicBool::new(false));
    signal_hook::flag::register(signal_hook::SIGTERM, Arc::clone(&term))?;
    while !term.load(Ordering::Relaxed) {
        // Do some time-limited stuff here
        // (if this could block forever, then there's no guarantee the signal will have any
        // effect).

Asynchronous runtime support

If you are looking for integration with an asynchronous runtime take a look at one of the following adapter crates:

Feel free to open a pull requests if you want to add support for runtimes not mentioned above.



Cleaning up signals.


Module for actions setting flags.


An iterator over incoming signals.


Module with the self-pipe pattern.



An ID of registered action.



List of forbidden signals.




Registers an arbitrary action for the given signal.


Removes a previously installed action.