diff options
author | bnewbold <bnewbold@robocracy.org> | 2016-10-03 21:45:05 -0700 |
---|---|---|
committer | bnewbold <bnewbold@robocracy.org> | 2016-10-03 21:49:42 -0700 |
commit | 639fc1f0bd0be25c25218e8e7ed2e90e3dc5dcfb (patch) | |
tree | 3f7f0c674b81df3b1408f2a2ff970992296dd035 | |
parent | f4d2980a65ec659a41bb5fab2382853c65c8efc0 (diff) | |
download | einhyrningsins-639fc1f0bd0be25c25218e8e7ed2e90e3dc5dcfb.tar.gz einhyrningsins-639fc1f0bd0be25c25218e8e7ed2e90e3dc5dcfb.zip |
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!
-rw-r--r-- | src/main.rs | 45 |
1 files changed, 45 insertions, 0 deletions
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<TcpListener>, mut prog: Command, number: u64) { @@ -58,6 +59,26 @@ fn run(binds: Vec<TcpListener>, 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<TcpListener> = sock_addrs.iter().map(|sa| { TcpListener::bind(sa).unwrap() }).collect(); |