> After reading W. R. Stevens' APUE, UNPv1, this group's FAQ and related
> posts, and various web pages... my head is spinning. :o(
> I'm still not sure what would be considered portable and safe signal
> handling in my app described below:
> - My app does not directly call any pthread functions. However, it is
> linked with the pthread library since a 3rd party vendor's library I link
> with is threaded. Actually, in my Makefile, I do use "-mt" and "-
> lpthread". Does this matter (don't know but wanted to mention it in
> case it does)?
It matters in the sense that if somewhere another thread is started, there
are then at least two threads: The initial thread, where your own code
executes, and the other thread(s).
> - I've installed the same signal handler function for SIGTERM, SIGQUIT,
> SIGINT, and SIGABRT. I want to catch these in order to call fclose(),
> free(), and exit(). I've included each of these in a single function that
> I'd like to call after receiving one of the signals mentioned
Those three functions aren't async signal safe, and should not be called in
(or from) a signal handler, as the state of internal structures they use is
indeterminant when such a signal arrives (except under very restricted
> - I have a critical section of code that I'd like to make sure isn't
> interrupted or is performed atomically. It's basically a file copy
> (fread(), fwrite()) section that I'd like to either succeed or fail as
> one unit... not be interrupted in the middle of the file copy.
No way to do this that I can think of without the cooperation of all
threads in using the same mutex.
> - I call sleep() for a user-defined amount of time (currently 30 seconds)
> after the app's main loop (for(;;)) completes before looping
> Here's what I have currently:
> 1) I'm using WRS' "Signal()" and "signal()" functions, which use
> sigaction(), verbatim from his UNPv1 text. Should I still use this in
> 2003? Or is it considered outdated and/or unnecessary? Should I instead
> just call sigaction()?
> 2) Should I use the example from APUE's signals chapter where he talks
> about using sigsuspend() to protect my critical file copy code section
> from interruption?
I think the example uses it to protect from interruption by signals. It
doesn't protect from interruption by other things. (By "interruption" I
assume you mean giving up the CPU for another thread or for a signal
handler, not an "interrupted system call." Sorry if I've misunderstood.)
> 3) Do most UNIX releases nowadays support queued signals? How does this
> contrast with asynchronous signals? Are these terms synonymous?
I don't know about "most." Some do, but they are not required to support
queuing for other than the new realtime signals.
The terms aren't synonymous.
> 4) For reliability and safety reasons, do I need to implement some form
> of signal checking that calls select() and then checks a pipe after an
> arrived signal? This was discussed in another post to this group. I don't
> know if doing this is applicable in all situations or not.
It's a way of transforming the event of an arriving signal into a event
represented by a file descriptor, so you can merge it into a select that
may be there to wait on other things. Also, writing to a pipe with write is
async signal safe. Whether this is advantageous depends on the specifics of
what else the code is doing.
> Any help, suggestions or guidance would be most appreciated. I'm having
> trouble applying all the information I've read recently.
Cleaning up when one of the signals you mention arrives is certainly a
normal thing to want to do, but to be safe you can't do it directly,
usually. Instead, you have to record that the signal arrived and return
from the signal handler, and then check the flag or pipe or whatever later,
outside of the signal handler.
Another idea is to longjmp out of the signal handler but, wonder of
wonders, longjmp (and its variants) isn't async signal safe! So this is not
a good idea.
A completely safe and straightforward way to deal with signals is to use
threading along with the sigwait functions. It pauses until a signal
arrives and tells you what signal it was. Then, any code you execute is
done outside of a signal handler, so none of the restrictions apply. The
catch is, the function blocks, so it makes sense usually only in a thread
dedicated to that purpose.
> Many thanks, -Eric