annotate lib/fatal-signal.c @ 4786:83d8d561903a

Improved 'fatal-signal' module.
author Bruno Haible <bruno@clisp.org>
date Tue, 14 Oct 2003 12:09:12 +0000
parents 6708dc21dacc
children f64f1da7e350
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
4770
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1 /* Emergency actions in case of a fatal signal.
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
2 Copyright (C) 2003 Free Software Foundation, Inc.
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
3 Written by Bruno Haible <bruno@clisp.org>, 2003.
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
4
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
5 This program is free software; you can redistribute it and/or modify
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
6 it under the terms of the GNU General Public License as published by
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
7 the Free Software Foundation; either version 2, or (at your option)
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
8 any later version.
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
9
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
10 This program is distributed in the hope that it will be useful,
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
13 GNU General Public License for more details.
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
14
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
15 You should have received a copy of the GNU General Public License
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
16 along with this program; if not, write to the Free Software Foundation,
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
17 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
18
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
19
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
20 #ifdef HAVE_CONFIG_H
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
21 # include "config.h"
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
22 #endif
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
23
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
24 /* Specification. */
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
25 #include "fatal-signal.h"
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
26
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
27 #include <stdbool.h>
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
28 #include <stdlib.h>
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
29 #include <signal.h>
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
30 #include <string.h>
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
31 #if HAVE_UNISTD_H
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
32 # include <unistd.h>
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
33 #endif
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
34
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
35 #include "xalloc.h"
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
36
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
37 #define SIZEOF(a) (sizeof(a) / sizeof(a[0]))
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
38
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
39
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
40 /* ========================================================================= */
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
41
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
42
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
43 /* The list of fatal signals.
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
44 These are those signals whose default action is to terminate the process
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
45 without a core dump, except
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
46 SIGKILL - because it cannot be caught,
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
47 SIGALRM SIGUSR1 SIGUSR2 SIGPOLL SIGIO SIGLOST - because applications
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
48 often use them for their own purpose,
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
49 SIGPROF SIGVTALRM - because they are used for profiling,
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
50 SIGSTKFLT - because it is more similar to SIGFPE, SIGSEGV, SIGBUS,
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
51 SIGSYS - because it is more similar to SIGABRT, SIGSEGV,
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
52 SIGPWR - because it of too special use,
4786
83d8d561903a Improved 'fatal-signal' module.
Bruno Haible <bruno@clisp.org>
parents: 4770
diff changeset
53 SIGRTMIN...SIGRTMAX - because they are reserved for application use.
4770
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
54 plus
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
55 SIGXCPU, SIGXFSZ - because they are quite similar to SIGTERM. */
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
56
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
57 static const int fatal_signals[] =
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
58 {
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
59 /* ISO C 99 signals. */
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
60 #ifdef SIGINT
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
61 SIGINT,
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
62 #endif
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
63 #ifdef SIGTERM
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
64 SIGTERM,
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
65 #endif
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
66 /* POSIX:2001 signals. */
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
67 #ifdef SIGHUP
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
68 SIGHUP,
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
69 #endif
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
70 #ifdef SIGPIPE
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
71 SIGPIPE,
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
72 #endif
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
73 /* BSD signals. */
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
74 #ifdef SIGXCPU
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
75 SIGXCPU,
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
76 #endif
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
77 #ifdef SIGXFSZ
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
78 SIGXFSZ,
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
79 #endif
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
80 0
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
81 };
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
82
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
83 #define num_fatal_signals (SIZEOF (fatal_signals) - 1)
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
84
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
85
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
86 /* ========================================================================= */
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
87
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
88
4786
83d8d561903a Improved 'fatal-signal' module.
Bruno Haible <bruno@clisp.org>
parents: 4770
diff changeset
89 typedef void (*action_t) (void);
83d8d561903a Improved 'fatal-signal' module.
Bruno Haible <bruno@clisp.org>
parents: 4770
diff changeset
90
83d8d561903a Improved 'fatal-signal' module.
Bruno Haible <bruno@clisp.org>
parents: 4770
diff changeset
91 /* Type of an entry in the actions array.
83d8d561903a Improved 'fatal-signal' module.
Bruno Haible <bruno@clisp.org>
parents: 4770
diff changeset
92 The 'action' field is accessed from within the fatal_signal_handler(),
83d8d561903a Improved 'fatal-signal' module.
Bruno Haible <bruno@clisp.org>
parents: 4770
diff changeset
93 therefore we mark it as 'volatile'. */
83d8d561903a Improved 'fatal-signal' module.
Bruno Haible <bruno@clisp.org>
parents: 4770
diff changeset
94 typedef struct
83d8d561903a Improved 'fatal-signal' module.
Bruno Haible <bruno@clisp.org>
parents: 4770
diff changeset
95 {
83d8d561903a Improved 'fatal-signal' module.
Bruno Haible <bruno@clisp.org>
parents: 4770
diff changeset
96 volatile action_t action;
83d8d561903a Improved 'fatal-signal' module.
Bruno Haible <bruno@clisp.org>
parents: 4770
diff changeset
97 }
83d8d561903a Improved 'fatal-signal' module.
Bruno Haible <bruno@clisp.org>
parents: 4770
diff changeset
98 actions_entry_t;
83d8d561903a Improved 'fatal-signal' module.
Bruno Haible <bruno@clisp.org>
parents: 4770
diff changeset
99
4770
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
100 /* The registered cleanup actions. */
4786
83d8d561903a Improved 'fatal-signal' module.
Bruno Haible <bruno@clisp.org>
parents: 4770
diff changeset
101 static actions_entry_t static_actions[32];
83d8d561903a Improved 'fatal-signal' module.
Bruno Haible <bruno@clisp.org>
parents: 4770
diff changeset
102 static actions_entry_t * volatile actions = static_actions;
83d8d561903a Improved 'fatal-signal' module.
Bruno Haible <bruno@clisp.org>
parents: 4770
diff changeset
103 static sig_atomic_t volatile actions_count = 0;
4770
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
104 static size_t actions_allocated = SIZEOF (static_actions);
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
105
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
106
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
107 /* Uninstall the handlers. */
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
108 static inline void
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
109 uninstall_handlers ()
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
110 {
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
111 size_t i;
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
112
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
113 for (i = 0; i < num_fatal_signals; i++)
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
114 signal (fatal_signals[i], SIG_DFL);
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
115 }
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
116
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
117
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
118 /* The signal handler. It gets called asynchronously. */
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
119 static void
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
120 fatal_signal_handler (int sig)
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
121 {
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
122 for (;;)
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
123 {
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
124 /* Get the last registered cleanup action, in a reentrant way. */
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
125 action_t action;
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
126 size_t n = actions_count;
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
127 if (n == 0)
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
128 break;
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
129 n--;
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
130 actions_count = n;
4786
83d8d561903a Improved 'fatal-signal' module.
Bruno Haible <bruno@clisp.org>
parents: 4770
diff changeset
131 action = actions[n].action;
4770
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
132 /* Execute the action. */
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
133 action ();
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
134 }
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
135
4786
83d8d561903a Improved 'fatal-signal' module.
Bruno Haible <bruno@clisp.org>
parents: 4770
diff changeset
136 /* Now execute the signal's default action.
83d8d561903a Improved 'fatal-signal' module.
Bruno Haible <bruno@clisp.org>
parents: 4770
diff changeset
137 If signal() blocks the signal being delivered for the duration of the
83d8d561903a Improved 'fatal-signal' module.
Bruno Haible <bruno@clisp.org>
parents: 4770
diff changeset
138 signal handler's execution, the re-raised signal is delivered when this
83d8d561903a Improved 'fatal-signal' module.
Bruno Haible <bruno@clisp.org>
parents: 4770
diff changeset
139 handler returns; otherwise it is delivered already during raise(). */
4770
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
140 uninstall_handlers ();
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
141 #if HAVE_RAISE
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
142 raise (sig);
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
143 #else
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
144 kill (getpid (), sig);
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
145 #endif
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
146 }
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
147
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
148
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
149 /* Install the handlers. */
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
150 static inline void
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
151 install_handlers ()
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
152 {
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
153 size_t i;
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
154
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
155 for (i = 0; i < num_fatal_signals; i++)
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
156 signal (fatal_signals[i], &fatal_signal_handler);
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
157 }
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
158
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
159
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
160 /* Register a cleanup function to be executed when a catchable fatal signal
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
161 occurs. */
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
162 void
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
163 at_fatal_signal (action_t action)
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
164 {
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
165 static bool cleanup_initialized = false;
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
166 if (!cleanup_initialized)
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
167 {
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
168 install_handlers ();
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
169 cleanup_initialized = true;
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
170 }
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
171
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
172 if (actions_count == actions_allocated)
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
173 {
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
174 /* Extend the actions array. Note that we cannot use xrealloc(),
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
175 because then the cleanup() function could access an already
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
176 deallocated array. */
4786
83d8d561903a Improved 'fatal-signal' module.
Bruno Haible <bruno@clisp.org>
parents: 4770
diff changeset
177 actions_entry_t *old_actions = actions;
4770
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
178 size_t new_actions_allocated = 2 * actions_allocated;
4786
83d8d561903a Improved 'fatal-signal' module.
Bruno Haible <bruno@clisp.org>
parents: 4770
diff changeset
179 actions_entry_t *new_actions =
83d8d561903a Improved 'fatal-signal' module.
Bruno Haible <bruno@clisp.org>
parents: 4770
diff changeset
180 xmalloc (new_actions_allocated * sizeof (actions_entry_t));
4770
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
181
4786
83d8d561903a Improved 'fatal-signal' module.
Bruno Haible <bruno@clisp.org>
parents: 4770
diff changeset
182 memcpy (new_actions, old_actions,
83d8d561903a Improved 'fatal-signal' module.
Bruno Haible <bruno@clisp.org>
parents: 4770
diff changeset
183 actions_allocated * sizeof (actions_entry_t));
4770
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
184 actions = new_actions;
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
185 actions_allocated = new_actions_allocated;
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
186 /* Now we can free the old actions array. */
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
187 if (old_actions != static_actions)
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
188 free (old_actions);
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
189 }
4786
83d8d561903a Improved 'fatal-signal' module.
Bruno Haible <bruno@clisp.org>
parents: 4770
diff changeset
190 /* The two uses of 'volatile' in the types above (and ISO C 99 section
83d8d561903a Improved 'fatal-signal' module.
Bruno Haible <bruno@clisp.org>
parents: 4770
diff changeset
191 5.1.2.3.(5)) ensure that we increment the actions_count only after
83d8d561903a Improved 'fatal-signal' module.
Bruno Haible <bruno@clisp.org>
parents: 4770
diff changeset
192 the new action has been written to the memory location
83d8d561903a Improved 'fatal-signal' module.
Bruno Haible <bruno@clisp.org>
parents: 4770
diff changeset
193 actions[actions_count]. */
83d8d561903a Improved 'fatal-signal' module.
Bruno Haible <bruno@clisp.org>
parents: 4770
diff changeset
194 actions[actions_count].action = action;
4770
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
195 actions_count++;
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
196 }
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
197
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
198
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
199 /* ========================================================================= */
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
200
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
201
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
202 #if HAVE_POSIX_SIGNALBLOCKING
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
203
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
204 static sigset_t fatal_signal_set;
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
205
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
206 static void
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
207 init_fatal_signal_set ()
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
208 {
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
209 static bool fatal_signal_set_initialized = false;
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
210 if (!fatal_signal_set_initialized)
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
211 {
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
212 size_t i;
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
213
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
214 sigemptyset (&fatal_signal_set);
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
215 for (i = 0; i < num_fatal_signals; i++)
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
216 sigaddset (&fatal_signal_set, fatal_signals[i]);
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
217
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
218 fatal_signal_set_initialized = true;
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
219 }
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
220 }
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
221
4786
83d8d561903a Improved 'fatal-signal' module.
Bruno Haible <bruno@clisp.org>
parents: 4770
diff changeset
222 /* Temporarily delay the catchable fatal signals. */
4770
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
223 void
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
224 block_fatal_signals ()
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
225 {
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
226 init_fatal_signal_set ();
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
227 sigprocmask (SIG_BLOCK, &fatal_signal_set, NULL);
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
228 }
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
229
4786
83d8d561903a Improved 'fatal-signal' module.
Bruno Haible <bruno@clisp.org>
parents: 4770
diff changeset
230 /* Stop delaying the catchable fatal signals. */
4770
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
231 void
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
232 unblock_fatal_signals ()
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
233 {
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
234 init_fatal_signal_set ();
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
235 sigprocmask (SIG_UNBLOCK, &fatal_signal_set, NULL);
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
236 }
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
237
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
238 #else
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
239
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
240 /* Don't bother caring about the old systems which don't have POSIX signal
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
241 blocking. */
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
242
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
243 void
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
244 block_fatal_signals ()
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
245 {
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
246 }
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
247
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
248 void
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
249 unblock_fatal_signals ()
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
250 {
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
251 }
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
252
6708dc21dacc New module 'fatal-signal'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
253 #endif