LIBS=$save_LIBS
CPPFLAGS=$save_CPPFLAGS
+AC_MSG_CHECKING([for feenableexcept])
+AC_LINK_IFELSE([AC_LANG_PROGRAM([[#define _GNU_SOURCE
+#include <fenv.h>]], [[feenableexcept(FE_DIVBYZERO)]])],
+[AC_DEFINE([HAVE_FEENABLEEXCEPT], 1, [define if system has fenableexcept])],
+AC_MSG_RESULT([yes]),
+AC_MSG_RESULT([no]))
+
dnl Checks for header files.
AC_HEADER_STDC
AC_CHECK_HEADERS( \
# include <config.h>
#endif
-#if defined(__linux__) && defined(__i386__)
+#if defined(HAVE_FEENABLEEXCEPT)
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+#include <fenv.h>
+#elif defined(__linux__) && defined(__i386__)
# include <fpu_control.h>
#endif
#include <simgear/structure/exception.hxx>
#include <simgear/debug/logstream.hxx>
+#include <cstring>
#include <iostream>
using std::cerr;
using std::endl;
// foreward declaration.
void fgExitCleanup();
-#if defined(__linux__) && defined(__i386__)
+static bool fpeAbort = false;
+static void handleFPE(int);
+static void initFPE();
-static void handleFPE (int);
+#if defined(HAVE_FEENABLEEXCEPT)
+static void
+initFPE ()
+{
+ if (fpeAbort) {
+ int except = fegetexcept();
+ feenableexcept(except | FE_DIVBYZERO | FE_INVALID);
+ } else {
+ signal(SIGFPE, handleFPE);
+ }
+}
+
+static void handleFPE(int)
+{
+ feclearexcept(FE_ALL_EXCEPT);
+ signal(SIGFPE, handleFPE);
+}
+#elif defined(__linux__) && defined(__i386__)
static void
initFPE ()
initFPE();
SG_LOG(SG_GENERAL, SG_ALERT, "Floating point interrupt (SIGFPE)");
}
+#else
+static void handleFPE(int)
+{
+}
+
+static void initFPE()
+{
+}
#endif
#ifdef _MSC_VER
#endif
_bootstrap_OSInit = 0;
-#if defined(__linux__) && defined(__i386__)
- // Enable floating-point exceptions for Linux/x86
- initFPE();
-#elif defined(__FreeBSD__)
+#if defined(__FreeBSD__)
// Ignore floating-point exceptions on FreeBSD
- signal(SIGFPE, SIG_IGN);
+ signal(SIGFPE, SIG_IGN);
+#else
+ // Maybe Enable floating-point exceptions on Linux
+ for (int i = 0; i < argc; ++i) {
+ if (!strcmp("--enable-fpe", argv[i])) {
+ fpeAbort = true;
+ break;
+ }
+ }
+ initFPE();
#endif
#if !defined( _MSC_VER ) && !defined( __MINGW32__ )
signal(SIGPIPE, SIG_IGN);
return FG_OPTIONS_EXIT;
}
+static int
+fgOptFpe(const char* arg)
+{
+ // Actually handled in bootstrap.cxx
+}
+
static map<string,size_t> fgOptionMap;
/*
{"ai-scenario", true, OPTION_FUNC, "", false, "", fgOptScenario },
{"parking-id", true, OPTION_FUNC, "", false, "", fgOptParking },
{"version", false, OPTION_FUNC, "", false, "", fgOptVersion },
+ {"enable-fpe", false, OPTION_FUNC, "", false, "", fgOptFpe},
{0}
};