### Example of a C Signal Handler

The following code gives a simple example of a signal handler function for a single-thread program. It shows how your program can recover from a signal and continue to run successfully.

In the example, the function chkptr checks a given number of bytes in an area of storage and returns the number of bytes that you can access. Key lines in the program are linked to explanations below the sample.

    #include <signal.h>
    #include <setjmp.h>
    #include <string.h>
    #include <io.h>

    static void mysig(int sig);        /* signal handler prototype */
    static jmp_buf jbuf;               /* buffer for machine state */

    int chkptr(void * ptr, int size)
    {
       void (* oldsig)(int);           /* where to save the old signal handler */
       volatile char c;                /* volatile to ensure access occurs */
       int valid = 0;                  /* count of valid bytes */
       char * p = ptr;
       oldsig = signal(SIGSEGV,mysig); /* set the signal handler */
       if (!setjmp(jbuf))              /* provide a point for the */
       {                               /* signal handler to return to */
          while (size--)
          {
             c = *p++;                 /* check the storage and */
             valid++;                  /* increase the counter */ |
          }
       }
       signal(SIGSEGV,oldsig);         /* reset the signal handler */
       return valid;                   /* return number of valid bytes */
    }

    static void mysig(int sig)
    {                                  /* write to file handle 2(stderr) */
       char FileData[20];
       strcpy(FileData, "Signal Occurred.\n\r");
       write(2, FileData, 18)
                               /* return to the point of the setjmp call */
       longjmp(jbuf,1);
    }

Signal handling is controlled by the statments in the code as follows:

- The assignment to oldsig registers the signal handler mysig and saves the original handler in oldsig so that it can be reset at a later time.
- The call to setjmp saves the state of the thread in jbuf. When you call setjmp directly, it returns 0 and the code within the if statement is run.
- The while statement reads in and checks each byte of the buffer, incrementing valid for each byte successfully copied to c.
  Assuming that not all of the buffer space is available, at some point in the loop p points to a storage location the process cannot access. An operating system exception occurs and is translated by the IBM C and C++ Compilers library to the SIGSEGV signal. The library then resets the signal handler for SIGSEGV to SIG_DFL and calls mysig, the signal handler registered for SIGSEGV.
- The mysig function prints an error message and uses longjmp to return to the place of the setjmp call in chkptr. The handler calls _write, rather than printf, to output the message because calling critical functions can fail inside a signal handler.
  This function does not reset the signal handler for SIGSEGV, because that signal is not intended to occur again. In some cases, you may want to reset signal handling before the signal handler function ends.
- Control returns to setjmp, which returns a nonzero value because it is called through longjmp. The if condition is now false and execution falls to the call of signal that resets oldsig. This call resets signal handling for SIGSEGV to whatever it was when chkptr was entered.
- The function returns the number of valid bytes in the buffer.

Signals and Exceptions
Signal and Exception Handling