rust-ctrlc icon indicating copy to clipboard operation
rust-ctrlc copied to clipboard

Distinguish between different signals

Open henninglive opened this issue 8 years ago • 2 comments

This is in response to concerns raised by #21.

Currently we only allow the user to register a single handler that gets called for both SIGINT and SIGTERM. There is similar situation on Windows, Windows actually distinguishes between a CTRL-C event and CTRL-BREAK event, but we call the same handler for both. Our API should allow the user distinguish between the different signals and allow them to take different actions on different signals.

There are two different approaches we could take when implementing this, we can allow users to register different handlers per signal or we can pass the signal type as parameter to the handler. I am in favour of last option. Regardless of what option we choose, we need to come with a cross platform Signal Enum. Should we just throw Windows signal types and Unix signal types together in one Enum or should we try to map signal types from one platform to types on the other platform?

Another thing we should consider is that Windows supports events/signals similar to SIGTERM. A handler registered by SetConsoleCtrlHandler(), in addition to being called on CTRL+C and CTRL+BREAK, will also be called for the following events CTRL_CLOSE_EVENT, CTRL_LOGOFF_EVENT and CTRL_SHUTDOWN_EVENT. These events allow the user to preform clean up before termination, but unlike for CTRL-C events, the process will terminate when the handler routine is done executing regardless of what the return value of handler routine was. If we wanted to, we could try to use this to implement cross platform SIGTERM support, but we would have to work around the termination issue in some way. Edit: These events are probably closer in semantics to SIGHUP then SIGTERM.

There are also other Unix signals which might be worth exposing, like SIGCHLD, SIGCONT, SIGHUP, SIGTSTP, SIGUSR1 and SIGUSR2.

henninglive avatar Jun 17 '17 14:06 henninglive

I think this is a time for a serious decision making about whether we want CtrlC to be:

  • A simple easy to use wrapper around Ctrl-C signal (as I originally started it, and kept it that way)

or

  • A full blown cross-platform(ish) signal library

Originally I had planned the former, and rejected some improvement suggestions because of the simplicity vision. However, due to your massive contributions to the project (thanks a lot, by the way) I think no reason why wouldn't CtrlC do more than just handle SIGINT as long as we keep the original super-simple API.

I think mapping the signals together would be a better option; I would like to handle CtrlC and termination without knowing the details of either platform. I was even thinking of a more high level abstraction of the basics (ctrlc+termination) while allowing lower level access to signals if the user wants to go to the details. Something like:

enum Signal {
    Ctrlc(PlatformSignal),
    Termination(PlatformSignal),
    Other(PlatformSignal),
}

where PlatformSignal would be the signal type of a certain platform (nix::sys::signal::Signal on unix, and something similar for Windows).

Detegr avatar Jun 21 '17 17:06 Detegr

I'm in favor of having a moderately complex crate. I believe once you start trapping signals you'll want to trap more. Currently I'm looking at adding HUP/reload config support to Feather(a minecraft server) and it uses this crate.

cheako avatar Jan 01 '20 02:01 cheako

There are better signal handler libraries in the Rust ecosystem nowadays. I'm keeping ctrlc the simple wrapper it has always been.

Detegr avatar May 20 '23 18:05 Detegr