Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Signal handler for all signal

How can I register a signal handler for ALL signal, available on the running OS, using signal(3)?

My code looks like this:

void sig_handler(int signum)
{
    printf("Received signal %d\n", signum);
}


int main()
{
    signal(ALL_SIGNALS_??, sig_handler);
    while (1) {
        sleep(1);
    };
    return 0;
}
like image 727
kober Avatar asked Jun 22 '13 22:06

kober


People also ask

What does a signal handler do?

A signal handler is a function which is called by the target environment when the corresponding signal occurs. The target environment suspends execution of the program until the signal handler returns or calls longjmp() . Signal handlers can be set with signal() or sigaction() .

Does signal () call the signal handler?

signal() sets the disposition of the signal signum to handler, which is either SIG_IGN, SIG_DFL, or the address of a programmer- defined function (a "signal handler"). If the signal signum is delivered to the process, then one of the following happens: * If the disposition is set to SIG_IGN, then the signal is ignored.

Do signal handlers run concurrently?

Signal handlers run concurrently with main program (in same process). <= 1 pending signal per type per process No Queue! Just a bit per signal type. Signals of type S discarded while process has S signal pending.

What is a default signal handler?

A Default signal handler is associated with every signal that the kernel runs when handling that signal. The action that a script or program performs when it receives a signal is called the default actions. A default signal handler handles these types of different default actions.


2 Answers

Most systems have a macro NSIG or _NSIG (the former would not be available in standards-conformance mode since it violates the namespace) defined in signal.h such that a loop for (i=1; i<_NSIG; i++) will walk all signals. Also, on POSIX systems that have signal masks, CHAR_BIT*sizeof(sigset_t) is an upper bound on the number of signals which you could use as a fallback if neither NSIG nor _NSIG is defined.

like image 153
R.. GitHub STOP HELPING ICE Avatar answered Sep 18 '22 19:09

R.. GitHub STOP HELPING ICE


Signal handlers have to deal with reentrancy concerns and other problems. In practice, it's often more convenient to mask signals and then retrieve them from time to time. You can mask all signals (except SIGSTOP and SIGKILL, which you can't handle anyway) with this:

sigset_t all_signals;
sigfillset(&all_signals);
sigprocmask(SIG_BLOCK, &all_signals, NULL);

The code is slightly different if you're using pthreads. Call this in every thread, or (preferably) in the main thread before you create any others:

sigset_t all_signals;
sigfillset(&all_signals);
pthread_sigmask(SIG_BLOCK, &all_signals, NULL);

Once you've done that, you should periodically call sigtimedwait(2) like this:

struct timespec no_time = {0, 0};
siginfo_t result;
int rc = sigtimedwait(&all_signals, &result, &no_time);

If there is a signal pending, information about it will be placed in result and rc will be the signal number; if not, rc will be -1 and errno will be EAGAIN. If you're already calling select(2)/poll(2) (e.g. as part of some event-driven system), you may want to create a signalfd(2) instead and attach it to your event loop. In this case, you still need to mask the signals as shown above.

like image 28
Kevin Avatar answered Sep 22 '22 19:09

Kevin