blue-lang-cli 0.0.154

The blue command line: run, fmt, ast, erase, check.
#![deny(unsafe_code)]

use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::{Arc, OnceLock};

static FLAG: OnceLock<Arc<AtomicBool>> = OnceLock::new();

const STOPPED: &[u8] = b"\nblue: stopped (ctrl-c)\n";

#[cfg(unix)]
extern "C" fn on_interrupt(_: libc::c_int) {
    if let Some(flag) = FLAG.get() {
        flag.store(true, Ordering::SeqCst);
    }
}

#[cfg(unix)]
extern "C" fn on_stop(_: libc::c_int) {
    #[allow(unsafe_code)]
    unsafe {
        libc::write(2, STOPPED.as_ptr().cast(), STOPPED.len());
        libc::_exit(130);
    }
}

pub fn interrupt(flag: &Arc<AtomicBool>) {
    if FLAG.set(Arc::clone(flag)).is_err() {
        return;
    }
    #[cfg(unix)]
    handle(on_interrupt);
}

pub fn stop() {
    #[cfg(unix)]
    handle(on_stop);
}

#[cfg(unix)]
fn handle(handler: extern "C" fn(libc::c_int)) {
    #[allow(unsafe_code)]
    unsafe {
        let before = libc::signal(libc::SIGINT, handler as libc::sighandler_t);
        if before == libc::SIG_IGN {
            libc::signal(libc::SIGINT, libc::SIG_IGN);
        }
    }
}