How to catch signals in Rust

2019-04-20 07:38发布

I'm trying to write some code that will catch a signal like SIGTERM.

I found this and I also found How to handle blocking i/o in Rust, or long running external function calls in general.

But in the current Rust version (0.12 nightly) it seems like that std::io::signal::Listener was removed. Did it get put somewhere else? If so can someone point me to how to catch a signal?

标签: rust
2条回答
ゆ 、 Hurt°
2楼-- · 2019-04-20 07:56

I believe that std::io::signal module was removed in this pull request. It is claimed that proper signals handling was never implemented properly for native runtime, so you likely wouldn't be able to use it now anyway. This seems to be a tracking issue for this problem.

In the meantime, I think, you will have to drop down to the lowest-level unsafe functions from libc.

查看更多
一纸荒年 Trace。
3楼-- · 2019-04-20 08:13

At the time of writing this answer, there is an RFC for built-in signals.

I have had some success using the chan-signal crate:

#[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);

    // _sdone gets dropped which closes the channel and causes `rdone`
    // to unblock.
}
查看更多
登录 后发表回答