1/* Expression evaluation for plural form selection.
2   Copyright (C) 2000-2003, 2005 Free Software Foundation, Inc.
3   Written by Ulrich Drepper <drepper@cygnus.com>, 2000.
4
5   This program is free software; you can redistribute it and/or modify
6   it under the terms of the GNU General Public License as published by
7   the Free Software Foundation; either version 2, or (at your option)
8   any later version.
9
10   This program is distributed in the hope that it will be useful,
11   but WITHOUT ANY WARRANTY; without even the implied warranty of
12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   GNU General Public License for more details.
14
15   You should have received a copy of the GNU General Public License
16   along with this program; if not, write to the Free Software Foundation,
17   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
18
19#ifdef HAVE_CONFIG_H
20# include <config.h>
21#endif
22
23/* Specification.  */
24#include "plural-eval.h"
25
26#include <stddef.h>
27#include <signal.h>
28
29#include "plural-exp.h"
30
31
32#define STATIC /*extern*/
33
34/* Include the expression evaluation code from libintl, this time with
35   'extern' linkage.  */
36#include "eval-plural.h"
37
38
39/* Exit point.  Must be set before calling install_sigfpe_handler().  */
40sigjmp_buf sigfpe_exit;
41
42#if USE_SIGINFO
43
44/* Additional information that is set before sigfpe_exit is invoked.  */
45int sigfpe_code;
46
47/* Signal handler called in case of arithmetic exception (e.g. division
48   by zero) during plural_eval.  */
49static void
50sigfpe_handler (int sig, siginfo_t *sip, void *scp)
51{
52  sigfpe_code = sip->si_code;
53  siglongjmp (sigfpe_exit, 1);
54}
55
56#else
57
58/* Signal handler called in case of arithmetic exception (e.g. division
59   by zero) during plural_eval.  */
60static void
61sigfpe_handler (int sig)
62{
63  siglongjmp (sigfpe_exit, 1);
64}
65
66#endif
67
68void
69install_sigfpe_handler (void)
70{
71#if USE_SIGINFO
72  struct sigaction action;
73  action.sa_sigaction = sigfpe_handler;
74  action.sa_flags = SA_SIGINFO;
75  sigemptyset (&action.sa_mask);
76  sigaction (SIGFPE, &action, (struct sigaction *) NULL);
77#else
78  signal (SIGFPE, sigfpe_handler);
79#endif
80}
81
82void
83uninstall_sigfpe_handler (void)
84{
85#if USE_SIGINFO
86  struct sigaction action;
87  action.sa_handler = SIG_DFL;
88  action.sa_flags = 0;
89  sigemptyset (&action.sa_mask);
90  sigaction (SIGFPE, &action, (struct sigaction *) NULL);
91#else
92  signal (SIGFPE, SIG_DFL);
93#endif
94}
95