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(). */
40 sigjmp_buf sigfpe_exit;
41
42 #if USE_SIGINFO
43
44 /* Additional information that is set before sigfpe_exit is invoked. */
45 int sigfpe_code;
46
47 /* Signal handler called in case of arithmetic exception (e.g. division
48 by zero) during plural_eval. */
49 static void
sigfpe_handler(int sig,siginfo_t * sip,void * scp)50 sigfpe_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. */
60 static void
sigfpe_handler(int sig)61 sigfpe_handler (int sig)
62 {
63 siglongjmp (sigfpe_exit, 1);
64 }
65
66 #endif
67
68 void
install_sigfpe_handler(void)69 install_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
82 void
uninstall_sigfpe_handler(void)83 uninstall_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