From 20e58abf6080ce3b1d07bf32bf438684acb02bf2 Mon Sep 17 00:00:00 2001 From: rasul Date: Wed, 11 Dec 2019 14:59:21 -0600 Subject: [PATCH] add signal handling --- Cargo.lock | 28 ++++++++++++++++++++++++++++ Cargo.toml | 1 + src/main.rs | 1 + src/run.rs | 31 ++++++++++++++++++++++++++++--- 4 files changed, 58 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5264642..c07f737 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,5 +1,10 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +[[package]] +name = "arc-swap" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "arrayref" version = "0.3.5" @@ -415,6 +420,25 @@ dependencies = [ "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "signal-hook" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)", + "signal-hook-registry 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "signal-hook-registry" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "arc-swap 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "slab" version = "0.4.2" @@ -434,6 +458,7 @@ dependencies = [ "mio-child-process 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "signal-hook 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -525,6 +550,7 @@ dependencies = [ ] [metadata] +"checksum arc-swap 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d7b8a9123b8027467bce0099fe556c628a53c8d83df0507084c31e9ba2e39aff" "checksum arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0d382e583f07208808f6b1249e60848879ba3543f57c32277bf52d69c2f0f0ee" "checksum arrayvec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8" "checksum atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "1803c647a3ec87095e7ae7acfca019e98de5ec9a7d01343f611cf3152ed71a90" @@ -576,6 +602,8 @@ dependencies = [ "checksum rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783" "checksum serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)" = "1217f97ab8e8904b57dd22eb61cde455fa7446a9c1cf43966066da047c1f3702" "checksum serde_derive 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)" = "a8c6faef9a2e64b0064f48570289b4bf8823b7581f1d6157c1b52152306651d0" +"checksum signal-hook 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "7a9c17dd3ba2d36023a5c9472ecddeda07e27fd0b05436e8c1e0c8f178185652" +"checksum signal-hook-registry 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94f478ede9f64724c5d173d7bb56099ec3e2d9fc2774aac65d34b8b890405f41" "checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" "checksum syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)" = "dff0acdb207ae2fe6d5976617f887eb1e35a2ba52c13c7234c790960cdad9238" "checksum synstructure 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "67656ea1dc1b41b1451851562ea232ec2e5a80242139f7e679ceccfb5d61f545" diff --git a/Cargo.toml b/Cargo.toml index 2a41d51..71aa7d9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,4 +15,5 @@ mio = "0.6" mio-child-process = "0.2" serde = "1.0" serde_derive = "1.0" +signal-hook = { version = "0.1", features = ["mio-support"] } toml = "0.5" diff --git a/src/main.rs b/src/main.rs index a85c164..9b49f29 100644 --- a/src/main.rs +++ b/src/main.rs @@ -10,6 +10,7 @@ extern crate mio_child_process; extern crate serde; #[macro_use] extern crate serde_derive; +extern crate signal_hook; extern crate toml; mod app; diff --git a/src/run.rs b/src/run.rs index 2037217..dc2fc47 100644 --- a/src/run.rs +++ b/src/run.rs @@ -1,19 +1,37 @@ +use std::boxed::Box; use std::sync::mpsc::TryRecvError; use mio::{Events, Poll, PollOpt, Ready, Token}; use mio_child_process::{ProcessEvent, StdioChannel}; +use signal_hook::iterator::Signals; + use crate::proc::Proc; use crate::result::Result; /// check for holds and start the loop +/// then do stuffs? pub fn run(procs: Vec, holds: Option, poll: Poll) -> Result> { if holds.unwrap_or(0) < 1 { error!("no holds configured"); return Ok(procs); } - Ok(run_loop(procs, holds, poll)) + match Signals::new(&[signal_hook::SIGINT]) { + Ok(signals) => { + poll.register( + &signals, + Token(std::usize::MAX - 1), + Ready::readable(), + PollOpt::edge(), + )?; + Ok(run_loop(procs, holds, poll, signals)) + } + Err(e) => { + error!("unable to register signals: {}", e); + Err(Box::new(e)) + } + } } /// restart an App, return the new Proc or report error @@ -51,7 +69,7 @@ fn process_event_data(channel: StdioChannel, data: String, app_name: &str) { } /// run the main loop until out of holds -fn run_loop(procs: Vec, holds: Option, poll: Poll) -> Vec { +fn run_loop(procs: Vec, holds: Option, poll: Poll, signals: Signals) -> Vec { let mut procs = procs; let mut holds = holds; @@ -61,7 +79,14 @@ fn run_loop(procs: Vec, holds: Option, poll: Poll) -> Vec { poll.poll(&mut events, None).unwrap(); for event in events.iter() { - if let Some(i) = find_proc_by_token(event.token(), &procs) { + if event.token() == Token(std::usize::MAX - 1) { + for signal in signals.pending() { + match signal { + signal_hook::SIGINT => info!("received SIGINT"), + s => info!("got signal {}", s), + }; + } + } else if let Some(i) = find_proc_by_token(event.token(), &procs) { let mut proc = procs.remove(i); match proc.process.try_recv() {