]> git.ipfire.org Git - thirdparty/gettext.git/commitdiff
Avoid crash by SIGFPE during plural form expression evaluation.
authorBruno Haible <bruno@clisp.org>
Sun, 1 Oct 2023 18:18:23 +0000 (20:18 +0200)
committerBruno Haible <bruno@clisp.org>
Fri, 6 Oct 2023 14:25:03 +0000 (16:25 +0200)
Libraries (such as libintl and libgettextpo) should not raise signals, because
catching such signals cannot be done in a multithread-safe way.

* gettext-runtime/intl/plural-exp.h (enum eval_status): New enum items
PE_INTDIV, PE_INTOVF.
* gettext-runtime/intl/eval-plural.h (plural_eval_recurse): When a division
argument is zero, return status PE_INTDIV instead of raising SIGFPE.
* gettext-runtime/intl/dcigettext.c (INTDIV0_RAISES_SIGFPE): Remove macro.
Don't include <signal.h>.
* gettext-runtime/intl/configure.ac: Don't invoke gt_INTDIV0.
* gettext-runtime/intl/m4/intdiv0.m4: Remove file.
* gettext-runtime/intl/Makefile.am (ACLOCAL_AMFLAGS): Remove option '-I m4'.
(EXTRA_DIST): Remove m4/intdiv0.m4.
* autogen.sh: When invoking aclocal in gettext-runtime/intl, omit option
'-I m4'.

* gettext-tools/src/msgl-check.c: Don't include <setjmp.h>, <signal.h>.
(plural_expression_histogram): Don't invoke install_sigfpe_handler,
uninstall_sigfpe_handler.
(check_plural_eval): Don't invoke setjmp, install_sigfpe_handler,
uninstall_sigfpe_handler. Remove 'volatile' from array variable.
Produce error message when status PE_INTDIV or PE_INTOVF occurred.
* gettext-tools/src/plural-eval.h: Don't include <setjmp.h>.
(sigjmp_buf, sigsetjmp, siglongjmp): Remove definitions.
(USE_SIGINFO): Remove macro.
(sigfpe_exit, sigfpe_code, install_sigfpe_handler, uninstall_sigfpe_handler):
Remove declarations.
* gettext-tools/src/plural-eval.c: Don't include <signal.h>.
(sigfpe_exit, sigfpe_code): Remove variables.
(sigfpe_handler, install_sigfpe_handler, uninstall_sigfpe_handler): Remove
functions.
* gettext-tools/configure.ac: Don't invoke gt_SIGINFO.
* gettext-tools/m4/siginfo.m4: Remove file.
* gettext-tools/m4/Makefile.am (EXTRA_DIST): Remove it.

13 files changed:
autogen.sh
gettext-runtime/intl/Makefile.am
gettext-runtime/intl/configure.ac
gettext-runtime/intl/dcigettext.c
gettext-runtime/intl/eval-plural.h
gettext-runtime/intl/m4/intdiv0.m4 [deleted file]
gettext-runtime/intl/plural-exp.h
gettext-tools/configure.ac
gettext-tools/m4/Makefile.am
gettext-tools/m4/siginfo.m4 [deleted file]
gettext-tools/src/msgl-check.c
gettext-tools/src/plural-eval.c
gettext-tools/src/plural-eval.h

index 6df9cf4cdd7ad68bff82687406ecfb39c181af0c..094fe9756a5b44e252bd799f78b287881594adb2 100755 (executable)
@@ -438,7 +438,7 @@ dir0=`pwd`
 
 echo "$0: generating configure in gettext-runtime/intl..."
 cd gettext-runtime/intl
-aclocal -I ../../m4 -I ../m4 -I m4 -I gnulib-m4 \
+aclocal -I ../../m4 -I ../m4 -I gnulib-m4 \
   && autoconf \
   && autoheader && touch config.h.in \
   && touch ChangeLog \
index ea166277b02e50c92579817fa3c5157c7857c960..4080b1f8a12ce68a70030a5c107dab5a9e1987b4 100644 (file)
 ## Process this file with automake to produce Makefile.in.
 
 AUTOMAKE_OPTIONS = 1.10 gnu no-dependencies
-ACLOCAL_AMFLAGS = -I ../../m4 -I ../m4 -I m4 -I gnulib-m4
+ACLOCAL_AMFLAGS = -I ../../m4 -I ../m4 -I gnulib-m4
 
 SUBDIRS = gnulib-lib
 
-EXTRA_DIST = \
-  m4/intdiv0.m4
+EXTRA_DIST =
 BUILT_SOURCES =
 MOSTLYCLEANFILES = core *.stackdump
 CLEANFILES =
index 190d9a8bfcf4a473962d3adef21feabe3f2867ae..b68c4000ee0c308af1f218569a022d1853bc068e 100644 (file)
@@ -118,7 +118,6 @@ AC_C_INLINE
 AC_TYPE_SIZE_T
 AC_FUNC_ALLOCA
 AC_FUNC_MMAP
-gt_INTDIV0
 gl_LOCK
 
 AC_LINK_IFELSE(
index 7bdc7a76095ef7853c61557bb856ac6c69318063..56bcea2fc9988ff2565ee16c1cd99ce78fce3f20 100644 (file)
@@ -69,20 +69,6 @@ extern int errno;
 
 #include <locale.h>
 
-#ifdef _LIBC
-  /* Guess whether integer division by zero raises signal SIGFPE.
-     Set to 1 only if you know for sure.  In case of doubt, set to 0.  */
-# if defined __alpha__ || defined __arm__ || defined __i386__ \
-     || defined __m68k__ || defined __s390__
-#  define INTDIV0_RAISES_SIGFPE 1
-# else
-#  define INTDIV0_RAISES_SIGFPE 0
-# endif
-#endif
-#if !INTDIV0_RAISES_SIGFPE
-# include <signal.h>
-#endif
-
 #if defined HAVE_SYS_PARAM_H || defined _LIBC
 # include <sys/param.h>
 #endif
index 90eb34050a66c247862165521183f3baa6ee5efd..d709642ccc3d87f3b2e6f6a01aa7a4cc88635834 100644 (file)
@@ -117,16 +117,12 @@ plural_eval_recurse (const struct expression *pexp, unsigned long int n,
              case mult:
                return OK (leftarg.value * rightarg.value);
              case divide:
-#if !INTDIV0_RAISES_SIGFPE
                if (rightarg.value == 0)
-                 raise (SIGFPE);
-#endif
+                 return (struct eval_result) { .status = PE_INTDIV };
                return OK (leftarg.value / rightarg.value);
              case module:
-#if !INTDIV0_RAISES_SIGFPE
                if (rightarg.value == 0)
-                 raise (SIGFPE);
-#endif
+                 return (struct eval_result) { .status = PE_INTDIV };
                return OK (leftarg.value % rightarg.value);
              case plus:
                return OK (leftarg.value + rightarg.value);
diff --git a/gettext-runtime/intl/m4/intdiv0.m4 b/gettext-runtime/intl/m4/intdiv0.m4
deleted file mode 100644 (file)
index 092a406..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-# intdiv0.m4 serial 9 (gettext-0.21.1)
-dnl Copyright (C) 2002, 2007-2008, 2010-2020 Free Software Foundation, Inc.
-dnl This file is free software; the Free Software Foundation
-dnl gives unlimited permission to copy and/or distribute it,
-dnl with or without modifications, as long as this notice is preserved.
-
-dnl From Bruno Haible.
-
-AC_DEFUN([gt_INTDIV0],
-[
-  AC_REQUIRE([AC_PROG_CC])dnl
-  AC_REQUIRE([AC_CANONICAL_HOST])dnl
-
-  AC_CACHE_CHECK([whether integer division by zero raises SIGFPE],
-    [gt_cv_int_divbyzero_sigfpe],
-    [
-      gt_cv_int_divbyzero_sigfpe=
-changequote(,)dnl
-      case "$host_os" in
-        macos* | darwin[6-9]* | darwin[1-9][0-9]*)
-          # On Mac OS X 10.2 or newer, just assume the same as when cross-
-          # compiling. If we were to perform the real test, 1 Crash Report
-          # dialog window would pop up.
-          case "$host_cpu" in
-            i[34567]86 | x86_64)
-              gt_cv_int_divbyzero_sigfpe="guessing yes" ;;
-          esac
-          ;;
-      esac
-changequote([,])dnl
-      if test -z "$gt_cv_int_divbyzero_sigfpe"; then
-        AC_RUN_IFELSE(
-          [AC_LANG_SOURCE([[
-#include <stdlib.h> /* for exit() */
-#include <signal.h>
-#if !(defined _WIN32 && !defined __CYGWIN__)
-#include <unistd.h> /* for _exit() */
-#endif
-
-static void
-sigfpe_handler (int sig)
-{
-  /* Exit with code 0 if SIGFPE, with code 1 if any other signal.  */
-  _exit (sig != SIGFPE);
-}
-
-int x = 1;
-int y = 0;
-int z;
-int inan;
-
-int main ()
-{
-  signal (SIGFPE, sigfpe_handler);
-/* IRIX and AIX (when "xlc -qcheck" is used) yield signal SIGTRAP.  */
-#if (defined (__sgi) || defined (_AIX)) && defined (SIGTRAP)
-  signal (SIGTRAP, sigfpe_handler);
-#endif
-/* Linux/SPARC yields signal SIGILL.  */
-#if defined (__sparc__) && defined (__linux__)
-  signal (SIGILL, sigfpe_handler);
-#endif
-
-  z = x / y;
-  inan = y / y;
-  exit (2);
-}
-]])],
-          [gt_cv_int_divbyzero_sigfpe=yes],
-          [gt_cv_int_divbyzero_sigfpe=no],
-          [
-            # Guess based on the CPU.
-changequote(,)dnl
-            case "$host_cpu" in
-              alpha* | i[34567]86 | x86_64 | m68k | s390*)
-                gt_cv_int_divbyzero_sigfpe="guessing yes";;
-              *)
-                gt_cv_int_divbyzero_sigfpe="guessing no";;
-            esac
-changequote([,])dnl
-          ])
-      fi
-    ])
-  case "$gt_cv_int_divbyzero_sigfpe" in
-    *yes) value=1 ;;
-    *)    value=0 ;;
-  esac
-  AC_DEFINE_UNQUOTED([INTDIV0_RAISES_SIGFPE], [$value],
-    [Define if integer division by zero raises signal SIGFPE.])
-])
index 7eb9aed8babd5c5e8af7c000c58dd95441150177..16080d63d36dcd57573605777c5acf8405c74b60 100644 (file)
@@ -117,6 +117,8 @@ extern void EXTRACT_PLURAL_EXPRESSION (const char *nullentry,
 enum eval_status
 {
   PE_OK,        /* Evaluation succeeded, produced a value */
+  PE_INTDIV,    /* Integer division by zero */
+  PE_INTOVF,    /* Integer overflow */
   PE_STACKOVF,  /* Stack overflow */
   PE_ASSERT     /* Assertion failure */
 };
index ff758dbbbd893c81991058f99ec6a1ab0154629c..74e92ca563db7c1fa143892fbe9b1d8ce1d6e6ef 100644 (file)
@@ -231,7 +231,6 @@ AC_TYPE_PID_T
 
 dnl Checks for library functions.
 AC_CHECK_FUNCS([select])
-gt_SIGINFO
 
 AC_C_BIGENDIAN([endianness=1], [endianness=0],
   [echo "AC-C-BIGENDIAN fails to work on your system." | sed -e 's,-,_,g' 1>&2
index 469de03a64f9a7217901d794e417bf7747c9b882..702309e7ab06fc9988be3b18598287f5044779ac 100644 (file)
@@ -46,5 +46,4 @@ EXTRA_DIST = \
   csharpexec-test.cs csharpexec-test.exe \
   exported.m4 \
   hostname.m4 \
-  locale-de.m4 \
-  siginfo.m4
+  locale-de.m4
diff --git a/gettext-tools/m4/siginfo.m4 b/gettext-tools/m4/siginfo.m4
deleted file mode 100644 (file)
index f39f6b5..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-# siginfo.m4 serial 2 (gettext-0.21.1)
-dnl Copyright (C) 2001-2002, 2020 Free Software Foundation, Inc.
-dnl This file is free software; the Free Software Foundation
-dnl gives unlimited permission to copy and/or distribute it,
-dnl with or without modifications, as long as this notice is preserved.
-
-# Determine how to determine the precise cause of a signal, for example
-# division by zero.
-# - SUSV2 and POSIX specify the use of sigaction with SA_SIGINFO and a member
-#   void (*)(int sig, siginfo_t *info, void *context) sa_sigaction.
-#   Linux (2.2.x and newer) and Solaris implement this.
-#   Linux (2.4.x and newer) on i386, m68k, sparc, sparc64, ia64 actually
-#   deliver FPE_INTDIV.
-# - Without SA_SIGINFO:
-#   - Linux on m68k calls the handler as
-#     void (*)(int sig, int code, struct sigcontext* scp).
-#     For division by zero, code would be VEC_ZERODIV<<2.
-#   - Linux on sparc calls the handler either as
-#     void (*)(int sig, int code, struct sigcontext* scp),
-#     code for division by zero would be SUBSIG_IDIVZERO, or as
-#     void (*)(int sig, siginfo_t *info, void *context).
-#     Which one depends on a process specific flag in the kernel.
-#   - Linux on sparc64 always calls the handler as
-#     void (*)(int sig, siginfo_t *info, void *context).
-#   - FreeBSD on i386 calls the handler as
-#     void (*)(int sig, int code, void* scp, char* addr).
-#     For division by zero, code would be FPE_INTDIV.
-#   - SunOS 4 calls the handler as
-#     void (*)(int sig, int code, void* scp, char* addr).
-#   - Solaris?
-#   - Irix 5, OSF/1, AIX call the handler as
-#     void (*)(int sig, int code, struct sigcontext *scp).
-# These are so many OS and CPU dependencies that we don't bother, and rely
-# only on SA_SIGINFO.
-AC_DEFUN([gt_SIGINFO],
-[
-  AC_CACHE_CHECK([for signal handlers with siginfo_t], gt_cv_siginfo_t,
-    [AC_COMPILE_IFELSE(
-       [AC_LANG_PROGRAM(
-          [[#include <signal.h>]],
-          [[struct sigaction action;
-            siginfo_t info;
-            action.sa_flags = SA_SIGINFO;
-            action.sa_sigaction = (void *) 0;
-          ]])],
-       [gt_cv_siginfo_t=yes],
-       [gt_cv_siginfo_t=no])])
-  if test $gt_cv_siginfo_t = yes; then
-    AC_DEFINE([HAVE_SIGINFO], [1],
-      [Define to 1 if <signal.h> defines the siginfo_t type and
-       struct sigaction has the sa_sigaction member and the SA_SIGINFO flag.])
-  fi
-])
index 0d4d98fdcc2b859784a98abddef43e404c1142d6..c048e71ec96bef57b31a2fef21b7b8e88d98bfd6 100644 (file)
@@ -23,8 +23,6 @@
 #include "msgl-check.h"
 
 #include <limits.h>
-#include <setjmp.h>
-#include <signal.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -69,9 +67,6 @@ plural_expression_histogram (const struct plural_distribution *self,
       unsigned long n;
       unsigned int count;
 
-      /* Protect against arithmetic exceptions.  */
-      install_sigfpe_handler ();
-
       count = 0;
       for (n = min; n <= max; n++)
         {
@@ -81,9 +76,6 @@ plural_expression_histogram (const struct plural_distribution *self,
             count++;
         }
 
-      /* End of protection against arithmetic exceptions.  */
-      uninstall_sigfpe_handler ();
-
       return count;
     }
   else
@@ -105,7 +97,7 @@ check_plural_eval (const struct expression *plural_expr,
   /* Do as if the plural formula assumes a value N infinitely often if it
      assumes it at least 5 times.  */
 #define OFTEN 5
-  unsigned char * volatile array;
+  unsigned char *array;
 
   /* Allocate a distribution array.  */
   if (nplurals_value <= 100)
@@ -114,116 +106,69 @@ check_plural_eval (const struct expression *plural_expr,
     /* nplurals_value is nonsense.  Don't risk an out-of-memory.  */
     array = NULL;
 
-  if (sigsetjmp (sigfpe_exit, 1) == 0)
-    {
-      unsigned long n;
-
-      /* Protect against arithmetic exceptions.  */
-      install_sigfpe_handler ();
+  unsigned long n;
 
-      for (n = 0; n <= 1000; n++)
+  for (n = 0; n <= 1000; n++)
+    {
+      struct eval_result res = plural_eval (plural_expr, n);
+      if (res.status != PE_OK)
         {
-          struct eval_result res = plural_eval (plural_expr, n);
-          if (res.status != PE_OK)
-            {
-              /* End of protection against arithmetic exceptions.  */
-              uninstall_sigfpe_handler ();
-
-              if (res.status == PE_STACKOVF)
-                po_xerror (PO_SEVERITY_ERROR, header, NULL, 0, 0, false,
-                           _("plural expression can produce stack overflow"));
-              else
-                /* Other res.status values should not occur.  */
-                abort ();
-
-              free (array);
-              return 1;
-            }
-
-          unsigned long val = res.value;
-
-          if ((long) val < 0)
-            {
-              /* End of protection against arithmetic exceptions.  */
-              uninstall_sigfpe_handler ();
-
-              po_xerror (PO_SEVERITY_ERROR, header, NULL, 0, 0, false,
-                         _("plural expression can produce negative values"));
-              free (array);
-              return 1;
-            }
-          else if (val >= nplurals_value)
-            {
-              char *msg;
-
-              /* End of protection against arithmetic exceptions.  */
-              uninstall_sigfpe_handler ();
-
-              msg = xasprintf (_("nplurals = %lu but plural expression can produce values as large as %lu"),
-                               nplurals_value, val);
-              po_xerror (PO_SEVERITY_ERROR, header, NULL, 0, 0, false, msg);
-              free (msg);
-              free (array);
-              return 1;
-            }
+          if (res.status == PE_INTDIV)
+            po_xerror (PO_SEVERITY_ERROR, header, NULL, 0, 0, false,
+                       _("plural expression can produce division by zero"));
+          else if (res.status == PE_INTOVF)
+            po_xerror (PO_SEVERITY_ERROR, header, NULL, 0, 0, false,
+                       _("plural expression can produce integer overflow"));
+          else if (res.status == PE_STACKOVF)
+            po_xerror (PO_SEVERITY_ERROR, header, NULL, 0, 0, false,
+                       _("plural expression can produce stack overflow"));
+          else
+            /* Other res.status values should not occur.  */
+            abort ();
 
-          if (array != NULL && array[val] < OFTEN)
-            array[val]++;
+          free (array);
+          return 1;
         }
 
-      /* End of protection against arithmetic exceptions.  */
-      uninstall_sigfpe_handler ();
+      unsigned long val = res.value;
 
-      /* Normalize the array[val] statistics.  */
-      if (array != NULL)
+      if ((long) val < 0)
         {
-          unsigned long val;
-
-          for (val = 0; val < nplurals_value; val++)
-            array[val] = (array[val] == OFTEN ? 1 : 0);
+          po_xerror (PO_SEVERITY_ERROR, header, NULL, 0, 0, false,
+                     _("plural expression can produce negative values"));
+          free (array);
+          return 1;
         }
-
-      distribution->expr = plural_expr;
-      distribution->often = array;
-      distribution->often_length = (array != NULL ? nplurals_value : 0);
-      distribution->histogram = plural_expression_histogram;
-
-      return 0;
-    }
-  else
-    {
-      /* Caught an arithmetic exception.  */
-      const char *msg;
-
-      /* End of protection against arithmetic exceptions.  */
-      uninstall_sigfpe_handler ();
-
-#if USE_SIGINFO
-      switch (sigfpe_code)
-#endif
+      else if (val >= nplurals_value)
         {
-#if USE_SIGINFO
-# ifdef FPE_INTDIV
-        case FPE_INTDIV:
-          msg = _("plural expression can produce division by zero");
-          break;
-# endif
-# ifdef FPE_INTOVF
-        case FPE_INTOVF:
-          msg = _("plural expression can produce integer overflow");
-          break;
-# endif
-        default:
-#endif
-          msg = _("plural expression can produce arithmetic exceptions, possibly division by zero");
+          char *msg =
+            xasprintf (_("nplurals = %lu but plural expression can produce values as large as %lu"),
+                       nplurals_value, val);
+          po_xerror (PO_SEVERITY_ERROR, header, NULL, 0, 0, false, msg);
+          free (msg);
+          free (array);
+          return 1;
         }
 
-      po_xerror (PO_SEVERITY_ERROR, header, NULL, 0, 0, false, msg);
+      if (array != NULL && array[val] < OFTEN)
+        array[val]++;
+    }
 
-      free (array);
+  /* Normalize the array[val] statistics.  */
+  if (array != NULL)
+    {
+      unsigned long val;
 
-      return 1;
+      for (val = 0; val < nplurals_value; val++)
+        array[val] = (array[val] == OFTEN ? 1 : 0);
     }
+
+  distribution->expr = plural_expr;
+  distribution->often = array;
+  distribution->often_length = (array != NULL ? nplurals_value : 0);
+  distribution->histogram = plural_expression_histogram;
+
+  return 0;
 #undef OFTEN
 }
 
index 82fbe56ef41d218c46b516405840920b145865d9..dac9a845f5fdd90e8c92e6b08a934d785e88bd5a 100644 (file)
@@ -1,5 +1,5 @@
 /* Expression evaluation for plural form selection.
-   Copyright (C) 2000-2003, 2005, 2019-2020 Free Software Foundation, Inc.
+   Copyright (C) 2000-2023 Free Software Foundation, Inc.
    Written by Ulrich Drepper <drepper@cygnus.com>, 2000.
 
    This program is free software: you can redistribute it and/or modify
@@ -23,7 +23,6 @@
 #include "plural-eval.h"
 
 #include <stddef.h>
-#include <signal.h>
 
 #include "plural-exp.h"
 
 /* Include the expression evaluation code from libintl, this time with
    'extern' linkage.  */
 #include "eval-plural.h"
-
-
-/* Exit point.  Must be set before calling install_sigfpe_handler().  */
-sigjmp_buf sigfpe_exit;
-
-#if USE_SIGINFO
-
-/* Additional information that is set before sigfpe_exit is invoked.  */
-int volatile sigfpe_code;
-
-/* Signal handler called in case of arithmetic exception (e.g. division
-   by zero) during plural_eval.  */
-static _GL_ASYNC_SAFE void
-sigfpe_handler (int sig, siginfo_t *sip, void *scp)
-{
-  sigfpe_code = sip->si_code;
-  /* This handler is invoked on the thread that caused the SIGFPE, that is,
-     the thread that is doing plural evaluation.  Therefore it's OK to use
-     siglongjmp.  */
-  siglongjmp (sigfpe_exit, 1);
-}
-
-#else
-
-/* Signal handler called in case of arithmetic exception (e.g. division
-   by zero) during plural_eval.  */
-static _GL_ASYNC_SAFE void
-sigfpe_handler (int sig)
-{
-  /* This handler is invoked on the thread that caused the SIGFPE, that is,
-     the thread that is doing plural evaluation.  Therefore it's OK to use
-     siglongjmp.  */
-  siglongjmp (sigfpe_exit, 1);
-}
-
-#endif
-
-void
-install_sigfpe_handler (void)
-{
-#if USE_SIGINFO
-  struct sigaction action;
-  action.sa_sigaction = sigfpe_handler;
-  action.sa_flags = SA_SIGINFO;
-  sigemptyset (&action.sa_mask);
-  sigaction (SIGFPE, &action, (struct sigaction *) NULL);
-#else
-  signal (SIGFPE, sigfpe_handler);
-#endif
-}
-
-void
-uninstall_sigfpe_handler (void)
-{
-#if USE_SIGINFO
-  struct sigaction action;
-  action.sa_handler = SIG_DFL;
-  action.sa_flags = 0;
-  sigemptyset (&action.sa_mask);
-  sigaction (SIGFPE, &action, (struct sigaction *) NULL);
-#else
-  signal (SIGFPE, SIG_DFL);
-#endif
-}
index d2b3ce983170a9a7d98e7efb0156ba1714f5e6ae..944965ef17e8c59aa186139a3c244cab54c73c9f 100644 (file)
 #include "plural-exp.h"
 
 
-/* Protection against signals during plural evaluation.  */
-
-#include <setjmp.h>
-
-/* Some platforms don't have the sigjmp_buf type in <setjmp.h>.  */
-#if defined _MSC_VER || defined __MINGW32__
-/* Native Woe32 API.  */
-# define sigjmp_buf jmp_buf
-# define sigsetjmp(env,savesigs) setjmp (env)
-# define siglongjmp longjmp
-#endif
-
-/* We use siginfo to get precise information about the signal.
-   But siginfo doesn't work on Irix 6.5 and on Cygwin 2005.  */
-#if HAVE_SIGINFO && !defined (__sgi) && !defined (__CYGWIN__)
-# define USE_SIGINFO 1
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Exit point.  Must be set before calling install_sigfpe_handler().  */
-extern sigjmp_buf sigfpe_exit;
-
-#if USE_SIGINFO
-/* Additional information that is set before sigfpe_exit is invoked.  */
-extern int volatile sigfpe_code;
-#endif
-
-/* Protect against signals during plural evaluation.  Must be called around
-   calls to plural_eval().  Must be called in pairs.  */
-extern void install_sigfpe_handler (void);
-extern void uninstall_sigfpe_handler (void);
-
-#ifdef __cplusplus
-}
-#endif
-
-
 #endif /* _PLURAL_EVAL_H */