Discussion:
String formatting in signal handler
Randi Botse
2012-10-20 15:03:49 UTC
Permalink
Hi List,

Almost (maybe all) function from the standard library stdio.h and
string.h are not safely to be called by signal handler. If so, how to
format string in a signal handler?. I want to log some signals which
sent to my program, the contents is for example: time, the signal
number itself, etc, and then write it to a file.

Regards.
--
To unsubscribe from this list: send the line "unsubscribe linux-c-programming" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Celelibi
2012-10-20 20:03:10 UTC
Permalink
Post by Randi Botse
Hi List,
Almost (maybe all) function from the standard library stdio.h and
string.h are not safely to be called by signal handler. If so, how to
format string in a signal handler?. I want to log some signals which
sent to my program, the contents is for example: time, the signal
number itself, etc, and then write it to a file.
Regards.
--
To unsubscribe from this list: send the line "unsubscribe
linux-c-programming" in
More majordomo info at http://vger.kernel.org/majordomo-info.html
Hi,

You can only call safely system calls listed in man 7 signal. write is
one of them. So you can reimplement some snprintf and write it.
But I wouldn't recommend that for several reasons.
1) The most important thing is that you should not call any syscall
inside a signal handler because :
1.1) a syscall may be blocking and thus preventing your program to run
and to handle those signals
1.2) a syscall usually have side effects, which might create a race
condition with respect to the main program. Especially, it modify
errno, and your main program may be preempted just between a syscall
and a test to errno.
2) You may need a buffer to implement your formatting and cannot call
malloc nor brk.
3) You need a loop! If you receive several signal at the same time,
you get notified only once. There is no signal counter.

So, you may still do your processing inside the signal handler if you
take care of all these points (and thoses I forgot). But I would
recommend that your handler set a (volatile) flag to 1 and you do not
use SA_RESTART. Thus, every time a signal is raised, the blocking
syscall will fail with EAGAIN and you can do your work inside your
main program without any limitation.
Thought you still have to take care of these points:
1) the flag MUST be volatile ;
2) you MUST loop because you may have received several signals ;
3) in order to lower the risk of race conditions, you MUST block the
signal from the time you test the flag to the time you've finished
your processing and reset the flag to 0.
4) If you have several syscalls in the main program, I'd suggest you
block the interesting signal almost every time, and you unblock it
only when you're about to perform some syscall you know they will be
long.


Celelibi
--
To unsubscribe from this list: send the line "unsubscribe linux-c-programming" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Loading...