#[cfg(any(linux_like, solarish, target_os = "hurd"))]
use core::num::NonZeroI32;
#[cfg(all(linux_kernel, feature = "io_uring"))]
use rustix::io_uring::Signal;
#[cfg(all(feature = "process", not(all(linux_kernel, feature = "io_uring"))))]
use rustix::process::Signal;
pub trait SignalExt: private::Sealed + Sized {
#[doc(alias = "SIGRTMIN", alias = "SIGRTMAX")]
#[cfg(any(linux_like, solarish, target_os = "hurd"))]
fn rt(n: i32) -> Option<Self>;
#[doc(alias = "SIGRTMIN")]
#[cfg(any(linux_like, solarish, target_os = "hurd"))]
fn rt_min() -> Self;
#[doc(alias = "SIGRTMAX")]
#[cfg(any(linux_like, solarish, target_os = "hurd"))]
fn rt_max() -> Self;
#[cfg(any(linux_like, solarish, target_os = "hurd"))]
fn from_raw(sig: i32) -> Option<Self>;
#[cfg(any(linux_like, solarish, target_os = "hurd"))]
fn from_raw_nonzero(non_zero: NonZeroI32) -> Option<Self>;
}
impl SignalExt for Signal {
#[cfg(any(linux_like, solarish, target_os = "hurd"))]
fn rt(n: i32) -> Option<Self> {
let min = libc::SIGRTMIN();
let sig = min.wrapping_add(n);
if sig >= min && sig <= libc::SIGRTMAX() {
unsafe { Some(Self::from_raw_unchecked(sig)) }
} else {
None
}
}
#[cfg(any(linux_like, solarish, target_os = "hurd"))]
fn rt_min() -> Self {
unsafe { Self::from_raw_unchecked(libc::SIGRTMIN()) }
}
#[cfg(any(linux_like, solarish, target_os = "hurd"))]
fn rt_max() -> Self {
unsafe { Self::from_raw_unchecked(libc::SIGRTMAX()) }
}
#[cfg(any(linux_like, solarish, target_os = "hurd"))]
fn from_raw(sig: i32) -> Option<Self> {
if let Some(non_zero) = NonZeroI32::new(sig) {
Self::from_raw_nonzero(non_zero)
} else {
None
}
}
#[cfg(any(linux_like, solarish, target_os = "hurd"))]
fn from_raw_nonzero(non_zero: NonZeroI32) -> Option<Self> {
#[cfg(any(
bsd,
solarish,
target_os = "aix",
target_os = "hermit",
all(
linux_kernel,
any(
target_arch = "mips",
target_arch = "mips32r6",
target_arch = "mips64",
target_arch = "mips64r6",
target_arch = "sparc",
target_arch = "sparc64"
)
)
))]
const SIGEMT: i32 = Signal::EMT.as_raw();
let sig = non_zero.get();
match sig {
libc::SIGHUP => Some(Self::HUP),
libc::SIGINT => Some(Self::INT),
libc::SIGQUIT => Some(Self::QUIT),
libc::SIGILL => Some(Self::ILL),
libc::SIGTRAP => Some(Self::TRAP),
libc::SIGABRT => Some(Self::ABORT),
libc::SIGBUS => Some(Self::BUS),
libc::SIGFPE => Some(Self::FPE),
libc::SIGKILL => Some(Self::KILL),
#[cfg(not(target_os = "vita"))]
libc::SIGUSR1 => Some(Self::USR1),
libc::SIGSEGV => Some(Self::SEGV),
#[cfg(not(target_os = "vita"))]
libc::SIGUSR2 => Some(Self::USR2),
libc::SIGPIPE => Some(Self::PIPE),
libc::SIGALRM => Some(Self::ALARM),
libc::SIGTERM => Some(Self::TERM),
#[cfg(not(any(
bsd,
solarish,
target_os = "aix",
target_os = "haiku",
target_os = "hurd",
target_os = "nto",
target_os = "vita",
all(
linux_kernel,
any(
target_arch = "mips",
target_arch = "mips32r6",
target_arch = "mips64",
target_arch = "mips64r6",
target_arch = "sparc",
target_arch = "sparc64"
),
)
)))]
libc::SIGSTKFLT => Some(Self::STKFLT),
#[cfg(not(target_os = "vita"))]
libc::SIGCHLD => Some(Self::CHILD),
#[cfg(not(target_os = "vita"))]
libc::SIGCONT => Some(Self::CONT),
#[cfg(not(target_os = "vita"))]
libc::SIGSTOP => Some(Self::STOP),
#[cfg(not(target_os = "vita"))]
libc::SIGTSTP => Some(Self::TSTP),
#[cfg(not(target_os = "vita"))]
libc::SIGTTIN => Some(Self::TTIN),
#[cfg(not(target_os = "vita"))]
libc::SIGTTOU => Some(Self::TTOU),
#[cfg(not(target_os = "vita"))]
libc::SIGURG => Some(Self::URG),
#[cfg(not(target_os = "vita"))]
libc::SIGXCPU => Some(Self::XCPU),
#[cfg(not(target_os = "vita"))]
libc::SIGXFSZ => Some(Self::XFSZ),
#[cfg(not(target_os = "vita"))]
libc::SIGVTALRM => Some(Self::VTALARM),
#[cfg(not(target_os = "vita"))]
libc::SIGPROF => Some(Self::PROF),
#[cfg(not(target_os = "vita"))]
libc::SIGWINCH => Some(Self::WINCH),
#[cfg(not(any(target_os = "haiku", target_os = "vita")))]
libc::SIGIO => Some(Self::IO),
#[cfg(not(any(bsd, target_os = "haiku", target_os = "hurd", target_os = "vita")))]
libc::SIGPWR => Some(Self::POWER),
libc::SIGSYS => Some(Self::SYS),
#[cfg(any(
bsd,
solarish,
target_os = "aix",
target_os = "hermit",
all(
linux_kernel,
any(
target_arch = "mips",
target_arch = "mips32r6",
target_arch = "mips64",
target_arch = "mips64r6",
target_arch = "sparc",
target_arch = "sparc64"
)
)
))]
SIGEMT => Some(Self::EMT),
#[cfg(bsd)]
libc::SIGINFO => Some(Self::INFO),
#[cfg(target_os = "freebsd")]
libc::SIGTHR => Some(Self::THR),
#[cfg(target_os = "freebsd")]
libc::SIGLIBRT => Some(Self::LIBRT),
_ => {
if sig >= libc::SIGRTMIN() && sig <= libc::SIGRTMAX() {
unsafe { Some(Self::from_raw_unchecked(sig)) }
} else {
None
}
}
}
}
}
mod private {
pub trait Sealed {}
impl Sealed for super::Signal {}
}
#[cfg(test)]
mod tests {
#[cfg(any(linux_like, solarish, target_os = "hurd"))]
use super::*;
#[cfg(any(linux_like, solarish, target_os = "hurd"))]
#[test]
fn test_sigrt() {
assert_eq!(libc::SIGRTMIN(), Signal::rt_min().as_raw());
assert_eq!(libc::SIGRTMIN(), Signal::rt_min().as_raw_nonzero().get());
assert_eq!(libc::SIGRTMAX(), Signal::rt_max().as_raw());
assert_eq!(libc::SIGRTMAX(), Signal::rt_max().as_raw_nonzero().get());
assert_eq!(Signal::rt(0).unwrap(), Signal::rt_min());
assert_ne!(Signal::rt(7).unwrap(), Signal::rt_min());
assert_ne!(Signal::rt(7).unwrap(), Signal::rt_max());
assert_eq!(Signal::rt(7).unwrap().as_raw(), libc::SIGRTMIN() + 7);
assert_eq!(
Signal::rt(7).unwrap().as_raw_nonzero().get(),
libc::SIGRTMIN() + 7
);
assert!(Signal::from_raw(0).is_none());
for raw in libc::SIGRTMIN()..=libc::SIGRTMAX() {
assert!(Signal::from_raw(raw).is_some());
}
assert!(Signal::from_raw(libc::SIGRTMIN() - 1).is_none());
assert!(Signal::from_raw(libc::SIGRTMAX() + 1).is_none());
}
}