Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tokio can't listen for signals between SIGRTMIN and SIGRTMAX #4554

Closed
weisbrja opened this issue Mar 2, 2022 · 1 comment · Fixed by #4555
Closed

tokio can't listen for signals between SIGRTMIN and SIGRTMAX #4554

weisbrja opened this issue Mar 2, 2022 · 1 comment · Fixed by #4555
Labels
A-tokio Area: The main tokio crate C-bug Category: This is a bug. M-signal Module: tokio/signal

Comments

@weisbrja
Copy link
Contributor

weisbrja commented Mar 2, 2022

Version
tokio v1.17.0

Platform
Linux thinkpad 5.16.11-arch1-1 #1 SMP PREEMPT Thu, 24 Feb 2022 02:18:20 +0000 x86_64 GNU/Linux

Description
I'm trying to listen to signals between libc::SIGRTMIN() and libc::SIGRTMAX(), which should be possible according to the POSIX standard (and it worked with the signal-hook crate).

I tried this code:

use tokio::signal::unix::{signal, SignalKind};

fn main() {
    let _signal = signal(SignalKind::from_raw(libc::SIGRTMIN() + 3)).unwrap();
}

And it panicked with "signal too large".

I tracked the error down with gdb, and the reason it fails, is because of this check in tokio/src/signal/unix.rs:

fn signal_enable(signal: SignalKind, handle: &Handle) -> io::Result<()> {
    // ...

    let globals = globals();
    let siginfo = match globals.storage().get(signal as EventId) {
        Some(slot) => slot,
        None => return Err(io::Error::new(io::ErrorKind::Other, "signal too large")),
    };

    // ...
}
@weisbrja weisbrja added A-tokio Area: The main tokio crate C-bug Category: This is a bug. labels Mar 2, 2022
@weisbrja
Copy link
Contributor Author

weisbrja commented Mar 3, 2022

I dug a bit in the source code and I think I found the issue.
The number of unix signals is defined in tokio/src/signal/unix.rs:

// Number of different unix signals
// (FreeBSD has 33)
const SIGNUM: usize = 33;

However, that is simply not true, because the POSIX standard allows for signals up to SIGRTMAX, which is greater than 33.

My proposed solution would be just replacing this:

// Number of different unix signals
// (FreeBSD has 33)
const SIGNUM: usize = 33;

impl Init for OsStorage {
    fn init() -> Self {
        (0..SIGNUM).map(|_| SignalInfo::default()).collect()
    }
}

With this:

impl Init for OsStorage {
    fn init() -> Self {
        (0..=libc::SIGRTMAX()).map(|_| SignalInfo::default()).collect()
    }
}

Any thoughts on this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-tokio Area: The main tokio crate C-bug Category: This is a bug. M-signal Module: tokio/signal
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants