It is important to minimize the time in signal handlers to prevent non-deterministic behavior.
The book suggests two-three main ways to deal with signal handlers
Set a global flag and exit.
The program can then check this flag periodically and deal with the issue.
Do some cleanup and exit.
Unwind the stack and go to some predetermined recovery spot in the program.
Why?
We assume that if you are catching signals your code is somehow critical.
Signals are not queued, so you may miss critical signals when you have them blocked.
It is not safe to call many system calls from within a signal handler
See 426 for the list of safe calls.
Note printf and << are not on this list.
A quick though experiment reviles why.
Most system calls are designed to be used in a "one time" fashion.
Consider printf or the stream insertion operator.
They must use some internal memory to convert an integer to the ascii string representing that integer.
This is probably done in some system area.
If the call is interrupted, with a second call to that function, then the internal state of the operation will be overwritten.
Functions with non-static local variables are safe.
Functions which use static or non-local variables are problematic.
Memory allocation uses a global structure.
most of the printf library, getpwnam, gethostbyname, ... use static system memory
errorno is problematic.
The author suggests declaring such flags as
volatile sig_atomic_t gSignalStatus = 0;
Volatile says don't store the value in a register, it must always be collected from and stored in memory.
sig_atomic_t is a type which can be read and written in a single instruction.
But this will not solve the fpe problem.
A second option is a non-local goto
GOTO's are BAD and you SHOULD NOT USE THEM unless necessary
#include <setjmp.h>
int setjmp(jmp_buf env);
int sigsetjmp(sigjmp_buf env, int savesigs);
void longjmp(jmp_buf env, int val);
void siglongjmp(sigjmp_buf env, int val);
sigsetjmp
saves a copy of the local environment, including the signal mask.
But it only saves the signal maks if the savesigs value is non zero.
On the inital call to sigsetjmp, a 0 is returned.
Other returns, as a result of siglongjmp, return a 1
siglongjmp
transfers control back to the point sgisetjmp was called.
Unwinds the stack
Stack pointer
PC (Instruction Pointer)
other registers.
The signal mask is restored. (Remember, it was possibly changed when the signal handler was called)