Date: Sunday, June 21, 2020 @ 22:03:22 Author: arojas Revision: 650296
ecl 20.04 rebuild Added: sagemath/trunk/sagemath-ecl-20.04.patch Modified: sagemath/trunk/PKGBUILD Deleted: sagemath/trunk/sagemath-ecl-sigfpe.patch ---------------------------+ PKGBUILD | 17 - sagemath-ecl-20.04.patch | 413 ++++++++++++++++++++++++++++++++++++++++++++ sagemath-ecl-sigfpe.patch | 147 --------------- 3 files changed, 419 insertions(+), 158 deletions(-) Modified: PKGBUILD =================================================================== --- PKGBUILD 2020-06-21 21:52:42 UTC (rev 650295) +++ PKGBUILD 2020-06-21 22:03:22 UTC (rev 650296) @@ -8,7 +8,7 @@ pkgbase=sagemath pkgname=(sagemath sagemath-jupyter) pkgver=9.1 -pkgrel=4 +pkgrel=5 pkgdesc="Open Source Mathematics Software, free alternative to Magma, Maple, Mathematica, and Matlab" arch=(x86_64) url="http://www.sagemath.org" @@ -39,7 +39,7 @@ test-optional.patch sagemath-cremona.patch sagemath-singular-4.1.2.patch - sagemath-ecl-sigfpe.patch + sagemath-ecl-20.04.patch sagemath-no-dict-sorting.patch sagemath-ipython7.patch sagemath-python-3.8.patch @@ -57,7 +57,7 @@ '887b931b0eb3c7fcfcb01ae0cfda9668925ed59740c4134cba13c43dfe0dd088' '937074fa7a8a4e2aba9ea77ec622fe937985a1a9176c48460d51325ee877a4f5' '4cb86b4f39f4e876450080e6ae5058ad2226d20b9cb3425ba0dc3e4368708434' - 'e44bbde87f3312548faad75b7383ef21fade55be251ab5804de41cd3842ca8a0' + '1fabc86d066310988a90083aaedceb9690822df8ff80c16501692231daa96e33' 'c6ac173198303cc3c719e9aa7e1e55c7353d6065184a0142c27bc3b82db255dd' 'fc28ca3aa1a656bfb451181d5086b3041238f24bf462cc69626d3cd603a246df' '9b24c5ccecaccb7bdd20c849d43ad048a2f5ade4fc9c359d22a8bf19b13012ca' @@ -78,8 +78,8 @@ patch -p1 -i ../sagemath-cremona.patch # Fixes for singular 4.1.2 https://trac.sagemath.org/ticket/25993 patch -p1 -i ../sagemath-singular-4.1.2.patch -# Fix SIGFPE crashes with ecl 16.1.3 https://trac.sagemath.org/ticket/22191 - patch -p1 -i ../sagemath-ecl-sigfpe.patch +# Fix build with ECL 20.04 https://trac.sagemath.org/ticket/22191 + patch -p1 -i ../sagemath-ecl-20.04.patch # Fix doc build with sphinx 3 https://trac.sagemath.org/ticket/28856 patch -p1 -i ../sagemath-sphinx-3.patch # Fix warnings with matplotlib 3.2 https://trac.sagemath.org/ticket/29547 @@ -120,10 +120,7 @@ build() { cd sage-$pkgver/src - export CC=gcc \ - SAGE_ROOT="$PWD" \ - SAGE_SRC="$PWD" \ - SAGE_NUM_THREADS=10 + export SAGE_NUM_THREADS=10 python setup.py build } @@ -132,8 +129,6 @@ cd sage-$pkgver/src - export SAGE_ROOT="$PWD" \ - SAGE_LOCAL="/usr" python setup.py install --root="$pkgdir" --optimize=1 mkdir -p "$pkgdir"/usr/bin Added: sagemath-ecl-20.04.patch =================================================================== --- sagemath-ecl-20.04.patch (rev 0) +++ sagemath-ecl-20.04.patch 2020-06-21 22:03:22 UTC (rev 650296) @@ -0,0 +1,413 @@ +diff --git a/src/sage/interfaces/interface.py b/src/sage/interfaces/interface.py +index 616c13d..430ba80 100644 +--- a/src/sage/interfaces/interface.py ++++ b/src/sage/interfaces/interface.py +@@ -589,9 +589,9 @@ class Interface(WithEqualityById, ParentWithBase): + EXAMPLES:: + + sage: maxima.quad_qags(x, x, 0, 1, epsrel=1e-4) +- [0.5,0.55511151231257...e-14,21,0] ++ [0.5,5.5511151231257...e-15,21,0] + sage: maxima.function_call('quad_qags', [x, x, 0, 1], {'epsrel':'1e-4'}) +- [0.5,0.55511151231257...e-14,21,0] ++ [0.5,5.5511151231257...e-15,21,0] + """ + args, kwds = self._convert_args_kwds(args, kwds) + self._check_valid_function_name(function) +diff --git a/src/sage/interfaces/maxima.py b/src/sage/interfaces/maxima.py +index 9ab456e..3e8f4a6 100644 +--- a/src/sage/interfaces/maxima.py ++++ b/src/sage/interfaces/maxima.py +@@ -128,9 +128,9 @@ http://maxima.sourceforge.net/docs/intromax/intromax.html. + + sage: a = maxima('(1 + sqrt(2))^5') + sage: float(a) +- 82.01219330881975 ++ 82.0121933088197... + sage: a.numer() +- 82.01219330881975 ++ 82.0121933088197... + + :: + +diff --git a/src/sage/interfaces/maxima_abstract.py b/src/sage/interfaces/maxima_abstract.py +index 86fbe75..ed3055d 100644 +--- a/src/sage/interfaces/maxima_abstract.py ++++ b/src/sage/interfaces/maxima_abstract.py +@@ -1518,7 +1518,7 @@ class MaximaAbstractElement(ExtraTabCompletion, InterfaceElement): + EXAMPLES:: + + sage: maxima('exp(-sqrt(x))').nintegral('x',0,1) +- (0.5284822353142306, 0.41633141378838...e-10, 231, 0) ++ (0.5284822353142306, 4.1633141378838...e-11, 231, 0) + + Note that GP also does numerical integration, and can do so to very + high precision very quickly:: +diff --git a/src/sage/interfaces/tests.py b/src/sage/interfaces/tests.py +index fc77f12..a6847a9 100644 +--- a/src/sage/interfaces/tests.py ++++ b/src/sage/interfaces/tests.py +@@ -31,8 +31,8 @@ Test that write errors to stderr are handled gracefully by GAP + ....: except IOError: + ....: f = open('/dev/null', 'w') + sage: kwds = dict(shell=True, stdout=f, stderr=f) +- sage: subprocess.call("echo syntax error | ecl", **kwds) +- 0 ++ sage: subprocess.call("echo syntax error | ecl", **kwds) in (0, 255) ++ True + sage: subprocess.call("echo syntax error | gap", **kwds) in (0, 1) + True + sage: subprocess.call("echo syntax error | gp", **kwds) +diff --git a/src/sage/libs/ecl.pxd b/src/sage/libs/ecl.pxd +index 4dd273f..f0b30de 100644 +--- a/src/sage/libs/ecl.pxd ++++ b/src/sage/libs/ecl.pxd +@@ -30,7 +30,7 @@ cdef extern from "ecl/ecl.h": + ctypedef long int cl_fixnum + ctypedef cl_fixnum cl_narg + ctypedef void *cl_object +- ctypedef unsigned int cl_index ++ ctypedef unsigned long int cl_index + + ctypedef enum ecl_option: + ECL_OPT_INCREMENTAL_GC = 0, +@@ -39,7 +39,6 @@ cdef extern from "ecl/ecl.h": + ECL_OPT_TRAP_SIGINT, + ECL_OPT_TRAP_SIGILL, + ECL_OPT_TRAP_SIGBUS, +- ECL_OPT_TRAP_SIGCHLD, + ECL_OPT_TRAP_SIGPIPE, + ECL_OPT_TRAP_INTERRUPT_SIGNAL, + ECL_OPT_SIGNAL_HANDLING_THREAD, +@@ -53,7 +52,6 @@ cdef extern from "ecl/ecl.h": + ECL_OPT_LISP_STACK_SAFETY_AREA, + ECL_OPT_C_STACK_SIZE, + ECL_OPT_C_STACK_SAFETY_AREA, +- ECL_OPT_SIGALTSTACK_SIZE, + ECL_OPT_HEAP_SIZE, + ECL_OPT_HEAP_SAFETY_AREA, + ECL_OPT_THREAD_INTERRUPT_SIGNAL, +@@ -127,6 +125,7 @@ cdef extern from "ecl/ecl.h": + cl_object cl_cddr(cl_object x) + cl_object cl_rplaca(cl_object x, cl_object v) + cl_object cl_rplacd(cl_object x, cl_object v) ++ cl_object ecl_list1(cl_object a) + + # string parsing and string IO + +@@ -147,6 +146,10 @@ cdef extern from "ecl/ecl.h": + int ecl_nvalues "NVALUES" + cl_object ecl_values "VALUES"(int n) + +- #Common Lisp "EQUAL" compatible hash function ++ # Common Lisp "EQUAL" compatible hash function + + cl_object cl_sxhash(cl_object key) ++ ++ # symbols ++ ++ cl_object ecl_make_symbol(const char *name, const char *package) +\ No newline at end of file +diff --git a/src/sage/libs/ecl.pyx b/src/sage/libs/ecl.pyx +index 1f05f4a..978e19b 100644 +--- a/src/sage/libs/ecl.pyx ++++ b/src/sage/libs/ecl.pyx +@@ -15,7 +15,7 @@ Library interface to Embeddable Common Lisp (ECL) + #adapted to work with pure Python types. + + from libc.stdlib cimport abort +-from libc.signal cimport SIGINT, SIGBUS, SIGSEGV, SIGCHLD ++from libc.signal cimport SIGINT, SIGBUS, SIGFPE, SIGSEGV + from libc.signal cimport raise_ as signal_raise + from posix.signal cimport sigaction, sigaction_t + cimport cysignals.signals +@@ -47,9 +47,16 @@ cdef extern from "eclsig.h": + void ecl_sig_off() + cdef sigaction_t ecl_sigint_handler + cdef sigaction_t ecl_sigbus_handler ++ cdef sigaction_t ecl_sigfpe_handler + cdef sigaction_t ecl_sigsegv_handler + cdef mpz_t ecl_mpz_from_bignum(cl_object obj) + cdef cl_object ecl_bignum_from_mpz(mpz_t num) ++ cdef cl_object conditions_to_handle_clobj ++ void safe_cl_boot(int argc, char** argv) ++ cl_object safe_cl_funcall(cl_object *error, cl_object fun, cl_object arg) ++ cl_object safe_cl_apply(cl_object *error, cl_object fun, cl_object args) ++ cl_object safe_cl_eval(cl_object *error, cl_object form) ++ + + cdef cl_object string_to_object(char * s): + return ecl_read_from_cstring(s) +@@ -93,9 +100,6 @@ cdef void remove_node(cl_object node): + + cdef cl_object list_of_objects + +-cdef cl_object safe_eval_clobj #our own error catching eval +-cdef cl_object safe_apply_clobj #our own error catching apply +-cdef cl_object safe_funcall_clobj #our own error catching funcall + cdef cl_object read_from_string_clobj #our own error catching reader + + cdef bint ecl_has_booted = 0 +@@ -139,7 +143,6 @@ def test_ecl_options(): + ECL_OPT_TRAP_SIGINT = 1 + ECL_OPT_TRAP_SIGILL = 1 + ECL_OPT_TRAP_SIGBUS = 1 +- ECL_OPT_TRAP_SIGCHLD = 0 + ECL_OPT_TRAP_SIGPIPE = 1 + ECL_OPT_TRAP_INTERRUPT_SIGNAL = 1 + ECL_OPT_SIGNAL_HANDLING_THREAD = 0 +@@ -153,7 +156,6 @@ def test_ecl_options(): + ECL_OPT_LISP_STACK_SAFETY_AREA = ... + ECL_OPT_C_STACK_SIZE = ... + ECL_OPT_C_STACK_SAFETY_AREA = ... +- ECL_OPT_SIGALTSTACK_SIZE = 1 + ECL_OPT_HEAP_SIZE = ... + ECL_OPT_HEAP_SAFETY_AREA = ... + ECL_OPT_THREAD_INTERRUPT_SIGNAL = ... +@@ -171,8 +173,6 @@ def test_ecl_options(): + ecl_get_option(ECL_OPT_TRAP_SIGILL))) + print('ECL_OPT_TRAP_SIGBUS = {0}'.format( + ecl_get_option(ECL_OPT_TRAP_SIGBUS))) +- print('ECL_OPT_TRAP_SIGCHLD = {0}'.format( +- ecl_get_option(ECL_OPT_TRAP_SIGCHLD))) + print('ECL_OPT_TRAP_SIGPIPE = {0}'.format( + ecl_get_option(ECL_OPT_TRAP_SIGPIPE))) + print('ECL_OPT_TRAP_INTERRUPT_SIGNAL = {0}'.format( +@@ -199,8 +199,6 @@ def test_ecl_options(): + ecl_get_option(ECL_OPT_C_STACK_SIZE))) + print('ECL_OPT_C_STACK_SAFETY_AREA = {0}'.format( + ecl_get_option(ECL_OPT_C_STACK_SAFETY_AREA))) +- print('ECL_OPT_SIGALTSTACK_SIZE = {0}'.format( +- ecl_get_option(ECL_OPT_SIGALTSTACK_SIZE))) + print('ECL_OPT_HEAP_SIZE = {0}'.format( + ecl_get_option(ECL_OPT_HEAP_SIZE))) + print('ECL_OPT_HEAP_SAFETY_AREA = {0}'.format( +@@ -231,10 +229,8 @@ def init_ecl(): + RuntimeError: ECL is already initialized + """ + global list_of_objects +- global safe_eval_clobj +- global safe_apply_clobj +- global safe_funcall_clobj + global read_from_string_clobj ++ global conditions_to_handle_clobj + global ecl_has_booted + cdef char *argv[1] + cdef sigaction_t sage_action[32] +@@ -243,9 +239,6 @@ def init_ecl(): + if ecl_has_booted: + raise RuntimeError("ECL is already initialized") + +- # we need it to stop handling SIGCHLD +- ecl_set_option(ECL_OPT_TRAP_SIGCHLD, 0); +- + #we keep our own GMP memory functions. ECL should not claim them + ecl_set_option(ECL_OPT_SET_GMP_MEMORY_FUNCTIONS,0); + +@@ -259,19 +252,14 @@ def init_ecl(): + + #initialize ECL + ecl_set_option(ECL_OPT_SIGNAL_HANDLING_THREAD, 0) +- cl_boot(1, argv) ++ safe_cl_boot(1, argv) + + #save signal handler from ECL + sigaction(SIGINT, NULL, &ecl_sigint_handler) + sigaction(SIGBUS, NULL, &ecl_sigbus_handler) ++ sigaction(SIGFPE, NULL, &ecl_sigfpe_handler) + sigaction(SIGSEGV, NULL, &ecl_sigsegv_handler) + +- #verify that no SIGCHLD handler was installed +- cdef sigaction_t sig_test +- sigaction(SIGCHLD, NULL, &sig_test) +- assert sage_action[SIGCHLD].sa_handler == NULL # Sage does not set SIGCHLD handler +- assert sig_test.sa_handler == NULL # And ECL bootup did not set one +- + #and put the Sage signal handlers back + for i in range(1,32): + sigaction(i, &sage_action[i], NULL) +@@ -293,32 +281,8 @@ def init_ecl(): + + read_from_string_clobj=cl_eval(string_to_object(b"(symbol-function 'read-from-string)")) + +- cl_eval(string_to_object(b""" +- (defun sage-safe-eval (form) +- (handler-case +- (values (eval form)) +- (serious-condition (cnd) +- (values nil (princ-to-string cnd))))) +- """)) +- safe_eval_clobj=cl_eval(string_to_object(b"(symbol-function 'sage-safe-eval)")) +- +- cl_eval(string_to_object(b""" +- (defun sage-safe-apply (func args) +- (handler-case +- (values (apply func args)) +- (serious-condition (cnd) +- (values nil (princ-to-string cnd))))) +- """)) +- +- safe_apply_clobj=cl_eval(string_to_object(b"(symbol-function 'sage-safe-apply)")) +- cl_eval(string_to_object(b""" +- (defun sage-safe-funcall (func arg) +- (handler-case +- (values (funcall func arg)) +- (serious-condition (cnd) +- (values nil (princ-to-string cnd))))) +- """)) +- safe_funcall_clobj=cl_eval(string_to_object(b"(symbol-function 'sage-safe-funcall)")) ++ conditions_to_handle_clobj=ecl_list1(ecl_make_symbol(b"SERIOUS-CONDITION", b"COMMON-LISP")) ++ insert_node_after(list_of_objects,conditions_to_handle_clobj) + + ecl_has_booted = 1 + +@@ -339,45 +303,46 @@ cdef cl_object ecl_safe_eval(cl_object form) except NULL: + ... + RuntimeError: ECL says: Console interrupt. + """ +- cdef cl_object s ++ cdef cl_object ret, error = NULL ++ + ecl_sig_on() +- cl_funcall(2,safe_eval_clobj,form) ++ ret = safe_cl_eval(&error,form) + ecl_sig_off() + +- if ecl_nvalues > 1: +- s = si_coerce_to_base_string(ecl_values(1)) ++ if error != NULL: ++ error = si_coerce_to_base_string(error) + raise RuntimeError("ECL says: {}".format( +- char_to_str(ecl_base_string_pointer_safe(s)))) ++ char_to_str(ecl_base_string_pointer_safe(error)))) + else: +- return ecl_values(0) ++ return ret + + cdef cl_object ecl_safe_funcall(cl_object func, cl_object arg) except NULL: +- cdef cl_object l, s +- l = cl_cons(func,cl_cons(arg,Cnil)); ++ cdef cl_object ret, error = NULL + + ecl_sig_on() +- cl_apply(2,safe_funcall_clobj,cl_cons(func,cl_cons(arg,Cnil))) ++ ret = safe_cl_funcall(&error,func,arg) + ecl_sig_off() + +- if ecl_nvalues > 1: +- s = si_coerce_to_base_string(ecl_values(1)) ++ if error != NULL: ++ error = si_coerce_to_base_string(error) + raise RuntimeError("ECL says: {}".format( +- char_to_str(ecl_base_string_pointer_safe(s)))) ++ char_to_str(ecl_base_string_pointer_safe(error)))) + else: +- return ecl_values(0) ++ return ret + + cdef cl_object ecl_safe_apply(cl_object func, cl_object args) except NULL: +- cdef cl_object s ++ cdef cl_object ret, error = NULL ++ + ecl_sig_on() +- cl_funcall(3,safe_apply_clobj,func,args) ++ ret = safe_cl_apply(&error,func,args) + ecl_sig_off() + +- if ecl_nvalues > 1: +- s = si_coerce_to_base_string(ecl_values(1)) ++ if error != NULL: ++ error = si_coerce_to_base_string(error) + raise RuntimeError("ECL says: {}".format( +- char_to_str(ecl_base_string_pointer_safe(s)))) ++ char_to_str(ecl_base_string_pointer_safe(error)))) + else: +- return ecl_values(0) ++ return ret + + cdef cl_object ecl_safe_read_string(char * s) except NULL: + cdef cl_object o +diff --git a/src/sage/libs/eclsig.h b/src/sage/libs/eclsig.h +index f9f2690..e249ccf 100644 +--- a/src/sage/libs/eclsig.h ++++ b/src/sage/libs/eclsig.h +@@ -11,15 +11,18 @@ + #include <signal.h> + static struct sigaction ecl_sigint_handler; + static struct sigaction ecl_sigbus_handler; ++static struct sigaction ecl_sigfpe_handler; + static struct sigaction ecl_sigsegv_handler; + static struct sigaction sage_sigint_handler; + static struct sigaction sage_sigbus_handler; ++static struct sigaction sage_sigfpe_handler; + static struct sigaction sage_sigsegv_handler; + + static inline void set_ecl_signal_handler(void) + { + sigaction(SIGINT, &ecl_sigint_handler, &sage_sigint_handler); + sigaction(SIGBUS, &ecl_sigbus_handler, &sage_sigbus_handler); ++ sigaction(SIGFPE, &ecl_sigfpe_handler, &sage_sigfpe_handler); + sigaction(SIGSEGV, &ecl_sigsegv_handler, &sage_sigsegv_handler); + } + +@@ -27,6 +30,7 @@ static inline void unset_ecl_signal_handler(void) + { + sigaction(SIGINT, &sage_sigint_handler, NULL); + sigaction(SIGBUS, &sage_sigbus_handler, NULL); ++ sigaction(SIGFPE, &sage_sigfpe_handler, NULL); + sigaction(SIGSEGV, &sage_sigsegv_handler, NULL); + } + +@@ -49,3 +53,52 @@ cl_object ecl_bignum_from_mpz(mpz_t num) + mpz_set(ecl_mpz_from_bignum(z), num); + return _ecl_big_register_copy(z); + } ++ ++static inline void safe_cl_boot(int argc, char** argv) { ++ ECL_WITH_LISP_FPE_BEGIN { ++ cl_boot(argc, argv); ++ } ECL_WITH_LISP_FPE_END; ++} ++ ++/* List of conditions to catch in the following functions. Is ++ * initialized after cl_boot in init_ecl. */ ++static cl_object conditions_to_handle_clobj = ECL_NIL; ++ ++static inline cl_object safe_cl_funcall(cl_object *error, cl_object fun, cl_object arg) { ++ cl_object ret = NULL; ++ cl_env_ptr the_env = ecl_process_env(); ++ ECL_WITH_LISP_FPE_BEGIN { ++ ECL_HANDLER_CASE_BEGIN(the_env, conditions_to_handle_clobj) { ++ ret = cl_funcall(2, fun, arg); ++ } ECL_HANDLER_CASE(1, condition) { ++ *error = cl_princ_to_string(condition); ++ } ECL_HANDLER_CASE_END; ++ } ECL_WITH_LISP_FPE_END; ++ return ret; ++} ++ ++static inline cl_object safe_cl_apply(cl_object *error, cl_object fun, cl_object args) { ++ cl_object ret = NULL; ++ cl_env_ptr the_env = ecl_process_env(); ++ ECL_WITH_LISP_FPE_BEGIN { ++ ECL_HANDLER_CASE_BEGIN(the_env, conditions_to_handle_clobj) { ++ ret = cl_apply(2, fun, args); ++ } ECL_HANDLER_CASE(1, condition) { ++ *error = cl_princ_to_string(condition); ++ } ECL_HANDLER_CASE_END; ++ } ECL_WITH_LISP_FPE_END; ++ return ret; ++} ++ ++static inline cl_object safe_cl_eval(cl_object *error, cl_object form) { ++ cl_object ret = NULL; ++ cl_env_ptr the_env = ecl_process_env(); ++ ECL_WITH_LISP_FPE_BEGIN { ++ ECL_HANDLER_CASE_BEGIN(the_env, conditions_to_handle_clobj) { ++ ret = cl_eval(form); ++ } ECL_HANDLER_CASE(1, condition) { ++ *error = cl_princ_to_string(condition); ++ } ECL_HANDLER_CASE_END; ++ } ECL_WITH_LISP_FPE_END; ++ return ret; ++} Deleted: sagemath-ecl-sigfpe.patch =================================================================== --- sagemath-ecl-sigfpe.patch 2020-06-21 21:52:42 UTC (rev 650295) +++ sagemath-ecl-sigfpe.patch 2020-06-21 22:03:22 UTC (rev 650296) @@ -1,147 +0,0 @@ -diff --git a/src/sage/libs/ecl.pyx b/src/sage/libs/ecl.pyx -index e408866..fa24ac0 100644 ---- a/src/sage/libs/ecl.pyx -+++ b/src/sage/libs/ecl.pyx -@@ -15,7 +15,7 @@ from __future__ import print_function, absolute_import - #adapted to work with pure Python types. - - from libc.stdlib cimport abort --from libc.signal cimport SIGINT, SIGBUS, SIGSEGV, SIGCHLD -+from libc.signal cimport SIGINT, SIGBUS, SIGSEGV, SIGCHLD, SIGFPE - from libc.signal cimport raise_ as signal_raise - from posix.signal cimport sigaction, sigaction_t - cimport cysignals.signals -@@ -47,9 +47,14 @@ cdef extern from "eclsig.h": - void ecl_sig_off() - cdef sigaction_t ecl_sigint_handler - cdef sigaction_t ecl_sigbus_handler -+ cdef sigaction_t ecl_sigfpe_handler - cdef sigaction_t ecl_sigsegv_handler - cdef mpz_t ecl_mpz_from_bignum(cl_object obj) - cdef cl_object ecl_bignum_from_mpz(mpz_t num) -+ cdef int fegetexcept() -+ cdef int feenableexcept(int) -+ cdef int fedisableexcept(int) -+ cdef int ecl_feflags - - cdef cl_object string_to_object(char * s): - return ecl_read_from_cstring(s) -@@ -238,6 +243,7 @@ def init_ecl(): - global ecl_has_booted - cdef char *argv[1] - cdef sigaction_t sage_action[32] -+ cdef int sage_fpes - cdef int i - - if ecl_has_booted: -@@ -257,6 +263,8 @@ def init_ecl(): - for i in range(1,32): - sigaction(i, NULL, &sage_action[i]) - -+ sage_fpes = fegetexcept() -+ - #initialize ECL - ecl_set_option(ECL_OPT_SIGNAL_HANDLING_THREAD, 0) - cl_boot(1, argv) -@@ -264,8 +272,12 @@ def init_ecl(): - #save signal handler from ECL - sigaction(SIGINT, NULL, &ecl_sigint_handler) - sigaction(SIGBUS, NULL, &ecl_sigbus_handler) -+ sigaction(SIGFPE, NULL, &ecl_sigfpe_handler) - sigaction(SIGSEGV, NULL, &ecl_sigsegv_handler) - -+ #save ECL's floating point exception flags -+ ecl_feflags = fegetexcept() -+ - #verify that no SIGCHLD handler was installed - cdef sigaction_t sig_test - sigaction(SIGCHLD, NULL, &sig_test) -@@ -276,6 +288,9 @@ def init_ecl(): - for i in range(1,32): - sigaction(i, &sage_action[i], NULL) - -+ fedisableexcept(ecl_feflags) -+ feenableexcept(sage_fpes) -+ - #initialise list of objects and bind to global variable - # *SAGE-LIST-OF-OBJECTS* to make it rooted in the reachable tree for the GC - list_of_objects=cl_cons(Cnil,cl_cons(Cnil,Cnil)) -@@ -319,7 +334,6 @@ def init_ecl(): - (values nil (princ-to-string cnd))))) - """)) - safe_funcall_clobj=cl_eval(string_to_object(b"(symbol-function 'sage-safe-funcall)")) -- - ecl_has_booted = 1 - - cdef cl_object ecl_safe_eval(cl_object form) except NULL: -diff --git a/src/sage/libs/eclsig.h b/src/sage/libs/eclsig.h -index f9f2690..a7e1f40 100644 ---- a/src/sage/libs/eclsig.h -+++ b/src/sage/libs/eclsig.h -@@ -9,24 +9,66 @@ - - - #include <signal.h> -+ -+/* Rummage around to determine how ECL was configured */ -+#define ECL_AVOID_FPE_H /* Prevent some local includes */ -+#include <ecl/config-internal.h> -+ -+#ifdef HAVE_FENV_H -+#include <fenv.h> -+#ifndef FE_ALL_EXCEPT -+#define FE_ALL_EXCEPT FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW | FE_INVALID -+#endif -+#else -+#ifndef FE_ALL_EXCEPT -+#define FE_ALL_EXCEPT 0 -+#endif -+#define feclearexcept(flags) do {} while (0) -+#endif -+ -+#ifndef HAVE_FEENABLEEXCEPT -+/* These are GNU extensions */ -+#define fegetexcept() 0 -+#define feenablexcept(flags) do {} while (0) -+#define fdisableexcept(flags) do {} while (0) -+#endif -+ - static struct sigaction ecl_sigint_handler; - static struct sigaction ecl_sigbus_handler; -+static struct sigaction ecl_sigfpe_handler; - static struct sigaction ecl_sigsegv_handler; - static struct sigaction sage_sigint_handler; - static struct sigaction sage_sigbus_handler; -+static struct sigaction sage_sigfpe_handler; - static struct sigaction sage_sigsegv_handler; -+static int ecl_feflags; -+static int sage_feflags; - - static inline void set_ecl_signal_handler(void) - { - sigaction(SIGINT, &ecl_sigint_handler, &sage_sigint_handler); - sigaction(SIGBUS, &ecl_sigbus_handler, &sage_sigbus_handler); -+ sigaction(SIGFPE, &ecl_sigfpe_handler, &sage_sigfpe_handler); - sigaction(SIGSEGV, &ecl_sigsegv_handler, &sage_sigsegv_handler); -+ -+ /* first clear pending floating point exceptions, if any */ -+ feclearexcept(FE_ALL_EXCEPT); -+ -+ /* sage_feflags should be 0; we don't set them otherwise */ -+ sage_feflags = fedisableexcept(FE_ALL_EXCEPT); -+ feenableexcept(ecl_feflags); - } - - static inline void unset_ecl_signal_handler(void) - { -+ /* clear pending exceptions and restore previous exception mask */ -+ feclearexcept(FE_ALL_EXCEPT); -+ ecl_feflags = fedisableexcept(FE_ALL_EXCEPT); -+ feenableexcept(sage_feflags); -+ - sigaction(SIGINT, &sage_sigint_handler, NULL); - sigaction(SIGBUS, &sage_sigbus_handler, NULL); -+ sigaction(SIGFPE, &sage_sigfpe_handler, NULL); - sigaction(SIGSEGV, &sage_sigsegv_handler, NULL); - } -