From c69052a62d527b3fe6d3d0852f67a04638403a4f Mon Sep 17 00:00:00 2001 From: Rain Date: Thu, 28 Nov 2024 03:18:27 +0000 Subject: [PATCH] signal: add SignalKind::info on illumos illumos has supported SIGINFO for a long time; see https://github.com/illumos/illumos-gate/commit/19d32b9ab53d17ac6605971e14c45a5281f8d9bb. --- tokio/src/signal/unix.rs | 17 +++++++++++++++-- tokio/tests/signal_info.rs | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 2 deletions(-) create mode 100644 tokio/tests/signal_info.rs diff --git a/tokio/src/signal/unix.rs b/tokio/src/signal/unix.rs index 59c0b5d9248..f8c3239cf61 100644 --- a/tokio/src/signal/unix.rs +++ b/tokio/src/signal/unix.rs @@ -23,13 +23,25 @@ pub(crate) type OsStorage = Box<[SignalInfo]>; impl Init for OsStorage { fn init() -> Self { // There are reliable signals ranging from 1 to 33 available on every Unix platform. - #[cfg(not(target_os = "linux"))] + #[cfg(not(any(target_os = "linux", target_os = "illumos")))] let possible = 0..=33; // On Linux, there are additional real-time signals available. #[cfg(target_os = "linux")] let possible = 0..=libc::SIGRTMAX(); + // On illumos, signal numbers go up to 41 (SIGINFO). The list of signals + // hasn't changed since 2013. See + // https://github.com/illumos/illumos-gate/blob/master/usr/src/uts/common/sys/iso/signal_iso.h. + // + // illumos also has real-time signals, but (a) the number of real-time + // signals is actually configurable at runtime and (b) this capability + // isn't exposed by libc as of 0.2.167, so we don't support them at the + // moment. If support for real-time signals on illumos is desired, this + // code would have to be changed to accommodate that. + #[cfg(target_os = "illumos")] + let possible = 0..=41; + possible.map(|_| SignalInfo::default()).collect() } } @@ -130,7 +142,8 @@ impl SignalKind { target_os = "freebsd", target_os = "macos", target_os = "netbsd", - target_os = "openbsd" + target_os = "openbsd", + target_os = "illumos" ))] pub const fn info() -> Self { Self(libc::SIGINFO) diff --git a/tokio/tests/signal_info.rs b/tokio/tests/signal_info.rs new file mode 100644 index 00000000000..c616ec34c8a --- /dev/null +++ b/tokio/tests/signal_info.rs @@ -0,0 +1,38 @@ +#![warn(rust_2018_idioms)] +#![cfg(feature = "full")] +#![cfg(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "illumos" +))] +#![cfg(not(miri))] // No `sigaction` on Miri + +mod support { + pub mod signal; +} +use support::signal::send_signal; + +use tokio::signal; +use tokio::signal::unix::SignalKind; +use tokio::sync::oneshot; + +#[tokio::test] +async fn siginfo() { + let mut sig = signal::unix::signal(SignalKind::info()).expect("installed signal handler"); + + let (fire, wait) = oneshot::channel(); + + // NB: simulate a signal coming in by exercising our signal handler + // to avoid complications with sending SIGINFO to the test process + tokio::spawn(async { + wait.await.expect("wait failed"); + send_signal(libc::SIGINFO); + }); + + let _ = fire.send(()); + + sig.recv().await.expect("received SIGINFO signal"); +}