summaryrefslogtreecommitdiff
path: root/meap/meap-code/ch10/ch10-handle/src/main.rs
blob: d40e329b437ff0053351aaeec3232dde2ad51f67 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
extern crate libc; // 0.2.42

use std::time::{Duration};
use std::thread::{sleep};
use libc::{signal,raise};
use libc::{SIG_DFL, SIG_IGN, SIGTERM, SIGHUP};

type handler_ptr = extern "C" fn(i32) -> ();

static mut ABORT: bool = false;

#[inline(never)]
extern "C" fn handle_signals(sig: i32) { // rustc will warn that that this code is never run
    let handle_signals_ptr: handler_ptr = handle_signals;
    unsafe { // set the signal handler again, to prevent it resetting to SIG_DFL
        signal(SIGTERM, std::mem::transmute(handle_signals_ptr));
    }
    
    let should_abort = match sig {
        SIGTERM => true,
        SIGHUP => false,
        _ => false,
    };
    
    unsafe { // make a quick update here, and defer the real work to somewhere else
        ABORT = should_abort;
    }
} 

fn main() {
    let delay = Duration::from_secs(1);

    // "main loop"
    for i in 1..=60 {
        unsafe { // at every step, check to see if a signal has been sent
            if ABORT {
                break;
            }
        }

        sleep(delay);
        println!(". {}", i);
        
        if i > 2 {
            unsafe { raise(SIGTERM); }
        }
    }
}