Search code examples
linuxsignals

Is it guaranteed that the kill() function will not return until the signal handler has done if a process kills itself?


Imagine the following program written in C:

void handler(int signo) {
    write(STDOUT_FILENO, "handler\n", 8);
}
int main() {
    signal(SIGUSR1, handler);
    kill(getpid(), SIGUSR1);
    write(STDOUT_FILENO, "after kill\n", 11);
}

If I run this program in Linux, is it possible the output is as follow:

after kill
handler

I tried many times, and the above result didn't appear.


Solution

  • puts is not good inside signals handlers. Read signal(7), puts is not async-signal-safe. You should use write(2) inside a signal handler (not puts).

    You have edited your question to use write instead of  puts

    And if you insist in wrongly using puts you should at least call fflush. But both are wrong inside signal handlers.

    (Don't forget that stdoutis buffered)

    BTW, it might happen (notably in multi-threaded application, where the signal handler is not running in the same thread that kill(2)-s the signal) that the signal handler is invoked after returning of kill

    I'm not sure that you are guaranteed that the signal handler of a single-threaded process is returning before kill, even if I believe that would happen on most Linux kernels. What you should be sure is that the signal handler would eventually be called (but you cannot be sure on when exactly). Also, a kernel is permitted to lose some signals (e.g. if an external thing or process is sending a lot of same signals). So called POSIX real-time signals are the exception, not the norm (see also this)

    If you have an event loop (e.g. around poll(2)) and accept to have Linux-specific code you could consider using signalfd(2) and polling it inside your event loop.