I'm having to work on a logging module that can be called from various places in a large project. The problem I have is that sometimes the module may be called from code executed inside a signal handler. Normally, the logging module includes time data using localtime() and strftime(), but of course these calls are not async-signal safe, and can cause deadlocks if called from within a signal handler. Is there any way (on a GNU/Linux system) to tell whether or not my code is currently executing in a signal handler context, apart from e.g., having every signal handler set a flag while processing? I think it would be better to simplify our signal handlers, but in this case I don't have a choice as to where the logging module might be called. It would be nice if I could test and just omit the timestamp information if the module is called during signal handling.
First of all, your question ("Am I in a signal handler?") does not have a well-defined answer. Consider the following code:
#include <setjmp.h>
#include <signal.h>
jmp_buf jb;
int foo(int s)
{
longjmp(jb,1);
}
int main()
{
if (setjmp(jb)) {
puts("Am I in a signal handler now, or not?");
return 0;
}
signal(SIGINT, foo);
raise(SIGINT);
}
With that said, there is a technique you could use to answer this question in a meaningful way for many programs. Choose a signal you don't intend to use, and add it to the sa_mask
for all the signals you handle, installing the signal handlers using sigaction
. Then you can use sigprocmask
to check the current signal mask, and if your designated signal is in the signal mask, that means a signal handler has been invoked and has not yet returned (returning would restore the original signal mask).