GNU Info

Info Node: (libc.info)Longjmp in Handler

(libc.info)Longjmp in Handler


Next: Signals in Handler Prev: Termination in Handler Up: Defining Handlers
Enter node , (file) or (file)node

Nonlocal Control Transfer in Handlers
-------------------------------------

   You can do a nonlocal transfer of control out of a signal handler
using the `setjmp' and `longjmp' facilities (Note: 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.  Note: 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 {
         ...
       }
     }


automatically generated by info2www version 1.2.2.9