From: John R. <jr...@Bi...> - 2003-07-07 02:57:22
|
On Wed, 2003-07-02 at 03:05, Nicholas Nethercote wrote: > Many > functions are non-reentrant, including lots of common ones like printf() > (most standard I/O functions, in fact) and malloc(). Yes, but in practice the glibc implementation of printf/fprintf can be used safely from a signal handler under restricted circumstances. The first is that malloc() must not be called [indirectly] from the signal handler. The reason why printf/fprintf would call malloc() is to allocate a buffer for the output characters. If the stream defaults to non-buffered, or if the buffer has been allocated already, then printf/fprintf does not call malloc. So, if there has been a [completed] call to printf/fprintf before the signal handler is invoked [this will allocate a buffer], or if the stream defaults to non-buffered [such as for fprintf(stderr, ...)], or if the program calls setvbuf() on the stream before the signal handler is invoked, then printf/fprintf need not call malloc(). Secondly, the usage from the handler must not collide with usage of the same stream from non-signal level. The easiest way is to segregate entirely the signal-level streams from the non-signal level streams, although a protocol for sharing a stream between signal level and non-signal level also is possible. You can also fdopen(dup(fileno(stream)), ...) [needs error checking] to obtain a separate stream "that goes to the same place" for use by a signal handler. [Output from the two streams will be intermixed.] Of course, this is not necessarily portable to non-glibc implementations. But it may be useful. |