Marin D wrote:

> As Glynn Clements noted yesterday many useful functions can't be safely
> called from within a signal handler because of their non-reentrant nature.
> 
> The problem is - how to handle cleanup code when the program is not "event
> driven" so there is no event-loop all of the time (for instance u are
> SIGINT-ed during a heavy computation). 

Stevens says that longjmp() may be called from within a signal handler
(this is an SVR4 extension; POSIX doesn't specify longjmp() as being
reentrant), so you can use e.g.

        if (setjmp(jbuf) == 0)
                the_program();
        else
                cleanup();

in your main() function.

> Also -  I/O calls are non-atomic (when dealing with data sizes over the 
> guaranteed atomic size which is 512 bytes for pipes by POSIX and 4096
> bytes in Linux, not sure for other calls) and they may be interrupted by
> signal. So u either check for EINTR (inconvinient) or use
> TEMP_FAILURE_RETRY macro , or set the SA_RESTART flag in sigaction(). 
> 
> And my question is - what happens when a SIGINT / SIGKILL arrives and
> interrupts the I/O call - will TEMP_FAILURE_RETRY be evaluated again as when 
> the above signals arrive the process will never switch back task mode
> (this may be no problem if the SA_RESTART flag is set as it doesn't imply 
> a swith to task mode, it will just resume the I/O primitive in kernel
> mode)

If you use SA_RESTART, then signals won't abort the system call. You
can either:

a) don't use SA_RESTART for signals which should terminate the program
(e.g. SIGINT), but only use it for signals which you wish to handle
asynchronously without affecting the control flow of the main program
(e.g. SIGCHLD, SIGALRM).

b) Use longjmp() from within the signal handler to call the cleanup
and termination code.

-- 
Glynn Clements <[EMAIL PROTECTED]>

Reply via email to