/*
fpe/fpe.c -- generic SIGFPE
Copyright (C) 2003 K. Scott Hunziker.
See the file COPYING for license, warranty, and permission details.
*/
static char rcsid[] =
"$Id: fpe.c,v 1.1 2003/08/09 18:13:15 ksh Exp $";
#if HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
#include <math.h>
#include <setjmp.h>
#include <signal.h>
#include <assert.h>
/*** floating point ***/
#if HAVE_FENV_H
#include <fenv.h>
#endif
#if HAVE_MACHINE_FPU_H
#include <machine/fpu.h>
#endif
#if HAVE_IEEEFP_H
#include <ieeefp.h>
#endif
#if HAVE_SIGINFO_H
#include <siginfo.h>
#endif
#if HAVE_UCONTEXT_H
#include <ucontext.h>
#endif
/**********************/
#if !SKIP_LOCAL_INCLUDES /* only used during configuration */
#include "exception.h"
#include "message.h"
#endif
void enable_fpe_traps (void);
#if HAVE_FEENABLEEXCEPT
extern int feenableexcept (int excepts);
#endif
/* Signal handler for floating point exceptions. */
#if HAVE_SIGACTION
static void
catch_sigfpe (sig, code, v)
int sig;
siginfo_t *code;
void *v;
{
assert (sig == SIGFPE);
switch (code->si_code)
{
case FPE_FLTDIV:
fail ("Floating point divide by zero.");
break;
case FPE_FLTOVF:
fail ("Floating point overflow.");
break;
case FPE_FLTRES:
fail ("Floating point inexact.");
break;
case FPE_FLTINV:
fail ("Floating point invalid.");
break;
default:
fail ("Floating point exception (%d).", code->si_code);
break;
}
raise_exception ();
}
#else
static RETSIGTYPE
catch_sigfpe (sig)
int sig;
{
assert (sig == SIGFPE);
fail ("Floating point exception.");
raise_exception ();
}
#endif
void
enable_fpe_traps ()
{
#if HAVE_SIGACTION
struct sigaction act;
act.sa_sigaction = catch_sigfpe; /* the signal handler */
if (sigemptyset (&(act.sa_mask))) /* no other signals blocked */
wipeout ("sigemptyset");
act.sa_flags = SA_SIGINFO; /* want 3 args for handler */
if (sigaction (SIGFPE, &act, NULL)) /* specify handler */
wipeout ("Bad sigaction call.");
if (sigemptyset (&(act.sa_mask))) /* unblock SIGFPE */
wipeout ("sigemptyset");
if (sigprocmask (SIG_SETMASK, &(act.sa_mask), NULL))
wipeout ("sigprocmask");
#else
(void) signal (SIGFPE, catch_sigfpe);
#endif
/* enable traps */
#if HAVE_FPSETMASK || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__)
(void) fpsetmask( FP_X_INV | FP_X_OFL | FP_X_DZ );
#elif HAVE_FEENABLEEXCEPT
(void) feenableexcept (FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW);
#elif HAVE_FPSETDEFAULTS
(void) fpsetdefaults();
#else
choke me
#endif
}
syntax highlighted by Code2HTML, v. 0.9.1