This crate provies experimental support for responding to OS signals using channels. Currently, this only works on Unix based systems, but I'd appreciate help adding Windows support.
Dual-licensed under MIT or the UNLICENSE.
https://burntsushi.net/rustdoc/chan_signal/.
Use is really simple. Just ask the chan_signal
crate to create a channel
subscribed to a set of signals. When a signal is sent to the process it will
be delivered to the channel.
use chan_signal::Signal;
let signal = chan_signal::notify(&[Signal::INT, Signal::TERM]);
// Blocks until this process is sent an INT or TERM signal.
// Since the channel is never closed, we can unwrap the received value.
signal.recv().unwrap();
When combined with chan_select!
from the chan
crate, one can easily
integrate signals with the rest of your program. For example, consider a
main function that waits for either normal completion of work (which is done
in a separate thread) or for a signal to be delivered:
#[macro_use]
extern crate chan;
extern crate chan_signal;
use chan_signal::Signal;
fn main() {
// Signal gets a value when the OS sent a INT or TERM signal.
let signal = chan_signal::notify(&[Signal::INT, Signal::TERM]);
// When our work is complete, send a sentinel value on `sdone`.
let (sdone, rdone) = chan::sync(0);
// Run work.
::std::thread::spawn(move || run(sdone));
// Wait for a signal or for work to be done.
chan_select! {
signal.recv() -> signal => {
println!("received signal: {:?}", signal)
},
rdone.recv() => {
println!("Program completed normally.");
}
}
}
fn run(sdone: chan::Sender<()>) {
println!("Running work for 5 seconds.");
println!("Can you send a signal quickly enough?");
// Do some work.
::std::thread::sleep_ms(5000);
// Quit normally.
sdone.send(());
}
TL;DR - Spawn a thread, block on sigwait
, deliver signals, repeat.