You can do a nonlocal transfer of control out of a signal handler using
the setjmp and longjmp facilities (see Non-Local Exits).
When the handler does a nonlocal control transfer, the part of the
program that was running will not continue. If this part of the program
was in the middle of updating an important data structure, the data
structure will remain inconsistent. Since the program does not
terminate, the inconsistency is likely to be noticed later on.
There are two ways to avoid this problem. One is to block the signal
for the parts of the program that update important data structures.
Blocking the signal delays its delivery until it is unblocked, once the
critical updating is finished. See Blocking Signals.
The other way to re-initialize the crucial data structures in the signal
handler, or make their values consistent.
Here is a rather schematic example showing the reinitialization of one
global variable.
#include <signal.h>
#include <setjmp.h>
jmp_buf return_to_top_level;
volatile sig_atomic_t waiting_for_input;
void
handle_sigint (int signum)
{
/* We may have been waiting for input when the signal arrived,but we are no longer waiting once we transfer control. */
waiting_for_input = 0;
longjmp (return_to_top_level, 1);
}
int
main (void)
{
...
signal (SIGINT, sigint_handler);
...
while (1) {
prepare_for_command ();
if (setjmp (return_to_top_level) == 0)
read_and_execute_command ();
}
}
/* Imagine this is a subroutine used by various commands. */
char *
read_data ()
{
if (input_from_terminal) {
waiting_for_input = 1;
...
waiting_for_input = 0;
} else {
...
}
}
Published under the terms of the GNU General Public License