shell/
signals.rs

1use std::sync::atomic::{AtomicBool, Ordering};
2
3use nix::{
4    libc,
5    sys::signal::{self, SigHandler, Signal, sigaction},
6};
7
8static SIG_INT: AtomicBool = AtomicBool::new(false);
9
10extern "C" fn sig_int_handle(_: libc::c_int, _: *mut libc::siginfo_t, _: *mut libc::c_void) {
11    SIG_INT.store(true, Ordering::Relaxed);
12}
13
14pub fn install_sigint_handler() -> bool {
15    let result = unsafe {
16        let sig_action = signal::SigAction::new(
17            signal::SigHandler::SigAction(sig_int_handle),
18            signal::SaFlags::empty(),
19            signal::SigSet::empty(),
20        );
21        sigaction(signal::SIGINT, &sig_action)
22    };
23
24    if let Err(errno) = result {
25        eprint!("ERROR Failed to install SIGINT handler due to: ");
26        eprintln!("{} ({}).", errno.desc(), errno);
27        false
28    } else {
29        true
30    }
31}
32
33pub fn mask_signals() {
34    /* Ignore interactive and job-control signals.  */
35    unsafe {
36        // Do not ignore SIGINT because we want the thread below to handle it (block it instead).
37        //signal::signal(Signal::SIGINT, SigHandler::SigIgn).unwrap();
38        signal::signal(Signal::SIGQUIT, SigHandler::SigIgn).unwrap();
39        signal::signal(Signal::SIGTSTP, SigHandler::SigIgn).unwrap();
40        signal::signal(Signal::SIGTTIN, SigHandler::SigIgn).unwrap();
41        signal::signal(Signal::SIGTTOU, SigHandler::SigIgn).unwrap();
42        // Ignoring sigchild will mess up waitpid and cause Command::spawn to panic under some conditions.
43        //signal::signal(Signal::SIGCHLD, SigHandler::SigIgn).unwrap();
44    }
45}
46
47pub fn test_clear_sigint() -> bool {
48    SIG_INT.swap(false, Ordering::Relaxed)
49}