#[cfg(feature = "extended-siginfo")]
#[cfg_attr(docsrs, doc(cfg(feature = "extended-siginfo")))]
pub mod origin;
pub mod raw;
#[cfg(feature = "extended-siginfo")]
pub use origin::WithOrigin;
pub use raw::WithRawSiginfo;
use std::sync::atomic::{AtomicBool, Ordering};
use libc::{c_int, siginfo_t};
mod sealed {
use std::fmt::Debug;
use libc::{c_int, siginfo_t};
pub unsafe trait Exfiltrator: Debug + Send + Sync + 'static {
type Storage: Debug + Default + Send + Sync + 'static;
type Output;
fn supports_signal(&self, sig: c_int) -> bool;
fn store(&self, slot: &Self::Storage, signal: c_int, info: &siginfo_t);
fn load(&self, slot: &Self::Storage, signal: c_int) -> Option<Self::Output>;
fn init(&self, slot: &Self::Storage, signal: c_int) {
let _ = slot;
let _ = signal;
}
}
}
pub trait Exfiltrator: sealed::Exfiltrator {}
impl<E: sealed::Exfiltrator> Exfiltrator for E {}
#[derive(Clone, Copy, Debug, Default)]
pub struct SignalOnly;
unsafe impl sealed::Exfiltrator for SignalOnly {
type Storage = AtomicBool;
fn supports_signal(&self, _: c_int) -> bool {
true
}
type Output = c_int;
fn store(&self, slot: &Self::Storage, _: c_int, _: &siginfo_t) {
slot.store(true, Ordering::SeqCst);
}
fn load(&self, slot: &Self::Storage, signal: c_int) -> Option<Self::Output> {
if slot
.compare_exchange(true, false, Ordering::SeqCst, Ordering::Relaxed)
.is_ok()
{
Some(signal)
} else {
None
}
}
}