From 639fc1f0bd0be25c25218e8e7ed2e90e3dc5dcfb Mon Sep 17 00:00:00 2001 From: bnewbold Date: Mon, 3 Oct 2016 21:45:05 -0700 Subject: basic/naive signal handling The goal here was to hook Ctrl-C and send USR2 signal to childred instead. Turns out this is doesn't work easily because Ctrl-C is sent to the entire process group, not just the top running process. Making this work would require either masking SIGINT in the childred (children might change this) or mucking with process groups, both of which are "meh". But, unsafe code, woooo! --- src/main.rs | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) (limited to 'src') diff --git a/src/main.rs b/src/main.rs index d4221dc..b7dee25 100644 --- a/src/main.rs +++ b/src/main.rs @@ -33,6 +33,7 @@ use std::net::ToSocketAddrs; use getopts::Options; use std::os::unix::io::IntoRawFd; +use nix::sys::signal; fn run(binds: Vec, mut prog: Command, number: u64) { @@ -58,6 +59,26 @@ fn run(binds: Vec, mut prog: Command, number: u64) { for mut c in children { c.wait().unwrap(); } + println!("Done."); +} + +static mut interrupted: bool = false; + +extern fn handle_hup(_: i32) { + println!("This is where I would restart all children gracefully?"); +} + +extern fn handle_int(_: i32) { + let first = unsafe { + let tmp = !interrupted; + interrupted = true; + tmp + }; + if first { + println!("Waiting for childred to shutdown gracefully (Ctrl-C again to bail)"); + } else { + panic!(); + } } fn print_usage(opts: Options) { @@ -112,6 +133,30 @@ fn main() { } builder.init().unwrap(); + println!("Registering signal handlers..."); + let mut mask_hup = signal::SigSet::empty(); + mask_hup.add(signal::Signal::SIGHUP); + mask_hup.add(signal::Signal::SIGUSR2); + let hup_action = signal::SigAction::new( + signal::SigHandler::Handler(handle_hup), + signal::SaFlags::empty(), + mask_hup); + + let mut mask_int = signal::SigSet::empty(); + mask_int.add(signal::Signal::SIGINT); + mask_int.add(signal::Signal::SIGTERM); + let int_action = signal::SigAction::new( + signal::SigHandler::Handler(handle_int), + signal::SaFlags::empty(), + mask_int); + + unsafe { + signal::sigaction(signal::Signal::SIGHUP, &hup_action).unwrap(); + signal::sigaction(signal::Signal::SIGUSR2, &hup_action).unwrap(); + signal::sigaction(signal::Signal::SIGINT, &int_action).unwrap(); + signal::sigaction(signal::Signal::SIGTERM, &int_action).unwrap(); + } + let binds: Vec = sock_addrs.iter().map(|sa| { TcpListener::bind(sa).unwrap() }).collect(); -- cgit v1.2.3