aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbnewbold <bnewbold@robocracy.org>2016-10-03 21:45:05 -0700
committerbnewbold <bnewbold@robocracy.org>2016-10-03 21:49:42 -0700
commit639fc1f0bd0be25c25218e8e7ed2e90e3dc5dcfb (patch)
tree3f7f0c674b81df3b1408f2a2ff970992296dd035
parentf4d2980a65ec659a41bb5fab2382853c65c8efc0 (diff)
downloadeinhyrningsins-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.rs45
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();