rdsh 0.5.2

Rust port/shim for dsh: fast launcher, token saver, zero behavior breakage via passthrough
//! Small signal bridge so local servers can clean up per-process handoff files.

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

static REQUESTED: AtomicBool = AtomicBool::new(false);

pub fn requested() -> bool {
    REQUESTED.load(Ordering::Relaxed)
}

#[cfg(unix)]
pub fn install(locale: crate::locale::Locale) -> anyhow::Result<()> {
    extern "C" fn request_shutdown(_: libc::c_int) {
        REQUESTED.store(true, Ordering::Relaxed);
    }

    unsafe {
        for signal in [libc::SIGINT, libc::SIGTERM] {
            if libc::signal(signal, request_shutdown as *const () as libc::sighandler_t)
                == libc::SIG_ERR
            {
                anyhow::bail!(match locale {
                    crate::locale::Locale::English =>
                        "could not install server shutdown signal handler",
                    crate::locale::Locale::Chinese => "无法安装服务器关闭信号处理程序",
                    crate::locale::Locale::Japanese =>
                        "サーバー終了シグナルハンドラーを設定できませんでした",
                });
            }
        }
    }
    Ok(())
}

#[cfg(windows)]
pub fn install(locale: crate::locale::Locale) -> anyhow::Result<()> {
    unsafe extern "system" fn request_shutdown(event: u32) -> i32 {
        const CTRL_C_EVENT: u32 = 0;
        const CTRL_BREAK_EVENT: u32 = 1;
        if event == CTRL_C_EVENT || event == CTRL_BREAK_EVENT {
            REQUESTED.store(true, Ordering::Relaxed);
            1
        } else {
            0
        }
    }

    #[link(name = "Kernel32")]
    unsafe extern "system" {
        fn SetConsoleCtrlHandler(
            handler: Option<unsafe extern "system" fn(u32) -> i32>,
            add: i32,
        ) -> i32;
    }

    if unsafe { SetConsoleCtrlHandler(Some(request_shutdown), 1) } == 0 {
        anyhow::bail!(match locale {
            crate::locale::Locale::English => "could not install server shutdown signal handler",
            crate::locale::Locale::Chinese => "无法安装服务器关闭信号处理程序",
            crate::locale::Locale::Japanese =>
                "サーバー終了シグナルハンドラーを設定できませんでした",
        });
    }
    Ok(())
}

#[cfg(not(any(unix, windows)))]
pub fn install(_locale: crate::locale::Locale) -> anyhow::Result<()> {
    Ok(())
}