The tokio-signal crate provides a tokio-based solution for handling signals. It's still in it's early stages though.
extern crate futures; extern crate tokio_core; extern crate tokio_signal; use futures::{Future, Stream}; use tokio_core::reactor::Core use tokio_signal::unix::{self as unix_signal, Signal}; use std::thread::{self, sleep}; use std::time::Duration; use std::sync::mpsc::{channel, Receiver}; fn run(signals: Receiver<i32>) { loop { if let Some(signal) = signals.try_recv() { eprintln!("received {} signal"); } sleep(Duration::from_millis(1)); } } fn main() { // Create channels for sending and receiving signals let (signals_tx, signals_rx) = channel(); // Execute the program with the receiving end of the channel // for listening to any signals that are sent to it. thread::spawn(move || run(signals_rx)); // Create a stream that will select over SIGINT, SIGTERM, and SIGHUP signals. let signals = Signal::new(unix_signal::SIGINT, &handle).flatten_stream() .select(Signal::new(unix_signal::SIGTERM, &handle).flatten_stream()) .select(Signal::new(unix_signal::SIGHUP, &handle).flatten_stream()); // Execute the event loop that will listen for and transmit received // signals to the shell. core.run(signals.for_each(|signal| { let _ = signals_tx.send(signal); Ok(()) })).unwrap(); }