diff options
| author | Jonas Maier <> | 2026-03-11 12:30:07 +0100 |
|---|---|---|
| committer | Jonas Maier <> | 2026-03-11 12:30:07 +0100 |
| commit | 15501132916dfbc24f23b619e6d5408f258fc0d9 (patch) | |
| tree | a77e27bfc139415baf7faf09eeaefec360db9423 /src/ctrlc.rs | |
| parent | b881eec59118bc630b64378476f4d5ada2bf5968 (diff) | |
| download | pish-15501132916dfbc24f23b619e6d5408f258fc0d9.tar.gz | |
can wait for threads & processes with a timeout now
Diffstat (limited to 'src/ctrlc.rs')
| -rw-r--r-- | src/ctrlc.rs | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/src/ctrlc.rs b/src/ctrlc.rs new file mode 100644 index 0000000..4c0153a --- /dev/null +++ b/src/ctrlc.rs @@ -0,0 +1,63 @@ +use crate::Session; +use libc::c_int; +use nix::sys::signal::*; +use std::sync::*; + +static SESSION: Mutex<Option<Arc<Mutex<Session>>>> = Mutex::new(None); + +fn handle() { + let Ok(mut se) = SESSION.lock() else { return }; + let Some(se) = se.as_mut() else { return }; + let Ok(mut se) = se.lock() else { return }; + se.ctrlc.pressed = true; +} + +extern "C" fn c_handle(_signal: c_int) { + // cannot propagate panic into C-land + let _ = std::panic::catch_unwind(|| { + if let Err(e) = std::panic::catch_unwind(handle) { + eprintln!("{e:?}"); // might panic + } + }); +} + +#[derive(Default)] +pub struct CtrlC { + pressed: bool, +} + +struct Teardown; +impl Drop for Teardown { + fn drop(&mut self) { + teardown(); + } +} + +fn teardown() { + unsafe { + let _ = signal(Signal::SIGINT, SigHandler::SigDfl); + } + if let Ok(mut se) = SESSION.lock() { + *se = None; + } +} + +#[must_use] +pub fn setup(session: Arc<Mutex<Session>>) -> impl Drop { + *SESSION.lock().unwrap() = Some(session); + unsafe { + signal(Signal::SIGINT, SigHandler::Handler(c_handle)) + .expect("failed to set ctrl+c signal handler"); + } + Teardown +} + +pub fn peek(session: &Session) -> bool { + session.ctrlc.pressed +} + +pub fn pop(session: &mut Session) -> bool { + let x = session.ctrlc.pressed; + session.ctrlc.pressed = false; + x +} |
