#include #include #include #include /* * Global declarations & references */ unsigned long *esp = 0; double resultval; extern void resumeloc(void); extern double divide(double,double); #if defined(TESTIT) double divide(double a, double b) { return(a/b); } #endif #define RESOK 1234.5678 /* * SIG_FPE signal hander */ void signal_fpe(sig, siginfo, scp) int sig; /* signal caught (SIGFPE) */ siginfo_t *siginfo; /* signal info, including address encountered */ struct sigcontext *scp; /* execution context when signal encountered */ { resultval = RESOK; /* result value set by resumeloc */ scp->sc_eip = (unsigned)resumeloc; /* continue execution at resumeloc */ return; } int main( int argc, char **argv) { struct sigaction sigact; fp_except_t exceptions; int rc; double result; memset((void *)&sigact, 0, sizeof(sigact)); sigact.sa_handler = (__sighandler_t *)signal_fpe; sigact.sa_flags = SA_RESTART|SA_SIGINFO; rc = sigaction(SIGFPE, &sigact, 0); if (rc != 0) { perror("sigaction"); exit(1); } exceptions = fpgetmask(); exceptions |= (FP_X_DZ + FP_X_OFL + FP_X_UFL); fpsetmask(exceptions); result = divide(1.0,0.0); if (result == RESOK) fprintf(stderr,"** Result correct: %g\n",result); else fprintf(stderr,"** Result incorrect: %g\n",result); return(0); }