aboutsummaryrefslogtreecommitdiffstats
path: root/src/main.rs
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 /src/main.rs
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!
Diffstat (limited to 'src/main.rs')
-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();