Solaris: Signals, SetJump, and FPE recovery

The code below employes a while loop that attempts a continuous computation, until a Floating-Point Error (FPE) triggers an SIGFPE interrupt.  Normally, a default handler, installed by the system typically during load time, will terminate the process; however, that handler can be replace by a programmer defined function within the process.  The idea it to have the programmer's defined function gracefully handle the situation.

The code below used three-strikes and your out handling for problems.

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <setjmp.h>

sigjmp_buf sjbuf;

#define MAX_TRIES 3
int error_count=0;                     /* Error count */

void grace(int );                        /* handler prototype */

void main(void) 
{
    int a,b,c,d;

    sigset( SIGFPE, grace);
    sigset( SIGINT, grace);

    while (1) {
        if ( sigsetjmp(sjbuf,1 ) == 0)  /* remember this point */
        {
                printf("Three numbers, please:\n");
                scanf("%d %d %d", &a, &b, &c);
                d = a*b/c;
                printf("%d*%d/%d = %d\n", a, b, c, d);
        }
    }
  } 
    void grace(int sig)
    {
    printf("sig is %d\n", sig);
    switch (sig) {                /* determine the cause of the signal */
        case SIGFPE :
                error_count++;
                if (error_count>MAX_TRIES)
                     {
                        printf("Thread terminating: max error count exceeded\n");
                        exit(0);
                       }
                printf("Aborting current computation\n");
                siglongjmp( sjbuf, 1);                /* return to problem area */
                break;
        case SIGINT :
                printf("Control-C depressed\n");
                exit(0);
                break;
        default:
                printf("Fatal Error\n");
                exit(0);
        }        
    }

last update:   10/16/00