Mercurial > hg > octave-nkf > gnulib-hg
annotate lib/fatal-signal.c @ 6259:96c32553b4c6
Use a consistent style for including <config.h>.
* __fpending.c, acl.c, argmatch.c,
argp-help.c, argp-parse.c,
argp-pvh.c, backupfile.c, basename.c, c-stack.c,
calloc.c, check-version.c, cloexec.c, closeout.c, copy-file.c,
creat-safer.c, cycle-check.c, dirfd.c, dirname.c, dup-safer.c,
dup2.c, euidaccess.c, exclude.c, exitfail.c, fatal-signal.c,
fd-safer.c, file-type.c, fileblocks.c, filemode.c,
filenamecat.c, findprog.c, fnmatch.c, fopen-safer.c, free.c,
fsusage.c, ftruncate.c, full-write.c, fwriteerror.c,
getaddrinfo.c, getcwd.c, getdelim.c, getline.c, getlogin_r.c,
getndelim2.c, getnline.c, getopt1.c, getpass.c, group-member.c,
hard-locale.c, hash-pjw.c, hash.c, human.c, idcache.c,
inet_ntop.c, isdir.c, long-options.c, malloc.c, memcasecmp.c,
memcmp.c, memcoll.c, memcpy.c, memmove.c, mkdir-p.c,
modechange.c, mountlist.c, open-safer.c, physmem.c,
pipe-safer.c, pipe.c, poll.c, posixver.c, progname.c,
progreloc.c, putenv.c, quote.c, quotearg.c, readline.c,
readlink.c, realloc.c, regex.c, rename.c, rmdir.c, rpmatch.c,
safe-read.c, same.c, save-cwd.c, savedir.c, sig2str.c,
strcspn.c, strerror.c, stripslash.c, strncasecmp.c, strndup.c,
strnlen.c, strnlen1.c, strsep.c, strstr.c, strtod.c,
strtoimax.c, strtol.c, strverscmp.c, tempname.c, time_r.c,
userspec.c, utimecmp.c, version-etc-fsf.c,
version-etc.c, wait-process.c, xalloc-die.c, xgetcwd.c,
xmalloc.c, xmemcoll.c, xnanosleep.c, xreadlink.c, xsetenv.c,
xstrndup.c, xstrtoimax.c, xstrtol.c, xstrtoumax.c, yesno.c:
Standardize inclusion of config.h.
* __fpending.h, dirfd.h, getdate.h, human.h,
inttostr.h: Removed inclusion of config.h from header files.
* inttostr.c: Adjusted in-tree users.
* timespec.h: Remove superfluous warning to include config.h.
* atexit.c, chdir-long.c chown.c, fchown-stub.c, getgroups.c,
gettimeofday.c, lchown.c, lstat.c, mkdir.c, mkstemp.c,
nanosleep.c, openat.c, raise.c, readtokens0.c, readutmp.c,
unlinkdir.c: Guard inclusion of config.h with HAVE_CONFIG_H.
author | Paul Eggert <eggert@cs.ucla.edu> |
---|---|
date | Mon, 19 Sep 2005 17:28:14 +0000 |
parents | a48fb0e98c8c |
children | 1b0092424a44 |
rev | line source |
---|---|
4770 | 1 /* Emergency actions in case of a fatal signal. |
5536
f64f1da7e350
Signals whose handler is set to SIG_IGN are not fatal.
Bruno Haible <bruno@clisp.org>
parents:
4786
diff
changeset
|
2 Copyright (C) 2003-2004 Free Software Foundation, Inc. |
4770 | 3 Written by Bruno Haible <bruno@clisp.org>, 2003. |
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, | |
5848
a48fb0e98c8c
*** empty log message ***
Paul Eggert <eggert@cs.ucla.edu>
parents:
5537
diff
changeset
|
17 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ |
4770 | 18 |
19 | |
20 #ifdef HAVE_CONFIG_H | |
6259
96c32553b4c6
Use a consistent style for including <config.h>.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5848
diff
changeset
|
21 # include <config.h> |
4770 | 22 #endif |
23 | |
24 /* Specification. */ | |
25 #include "fatal-signal.h" | |
26 | |
27 #include <stdbool.h> | |
28 #include <stdlib.h> | |
29 #include <signal.h> | |
30 #include <string.h> | |
31 #if HAVE_UNISTD_H | |
32 # include <unistd.h> | |
33 #endif | |
34 | |
35 #include "xalloc.h" | |
36 | |
37 #define SIZEOF(a) (sizeof(a) / sizeof(a[0])) | |
38 | |
39 | |
40 /* ========================================================================= */ | |
41 | |
42 | |
43 /* The list of fatal signals. | |
44 These are those signals whose default action is to terminate the process | |
45 without a core dump, except | |
46 SIGKILL - because it cannot be caught, | |
47 SIGALRM SIGUSR1 SIGUSR2 SIGPOLL SIGIO SIGLOST - because applications | |
48 often use them for their own purpose, | |
49 SIGPROF SIGVTALRM - because they are used for profiling, | |
50 SIGSTKFLT - because it is more similar to SIGFPE, SIGSEGV, SIGBUS, | |
51 SIGSYS - because it is more similar to SIGABRT, SIGSEGV, | |
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 | 54 plus |
55 SIGXCPU, SIGXFSZ - because they are quite similar to SIGTERM. */ | |
56 | |
5536
f64f1da7e350
Signals whose handler is set to SIG_IGN are not fatal.
Bruno Haible <bruno@clisp.org>
parents:
4786
diff
changeset
|
57 static int fatal_signals[] = |
4770 | 58 { |
59 /* ISO C 99 signals. */ | |
60 #ifdef SIGINT | |
61 SIGINT, | |
62 #endif | |
63 #ifdef SIGTERM | |
64 SIGTERM, | |
65 #endif | |
66 /* POSIX:2001 signals. */ | |
67 #ifdef SIGHUP | |
68 SIGHUP, | |
69 #endif | |
70 #ifdef SIGPIPE | |
71 SIGPIPE, | |
72 #endif | |
73 /* BSD signals. */ | |
74 #ifdef SIGXCPU | |
75 SIGXCPU, | |
76 #endif | |
77 #ifdef SIGXFSZ | |
78 SIGXFSZ, | |
79 #endif | |
80 0 | |
81 }; | |
82 | |
83 #define num_fatal_signals (SIZEOF (fatal_signals) - 1) | |
84 | |
5536
f64f1da7e350
Signals whose handler is set to SIG_IGN are not fatal.
Bruno Haible <bruno@clisp.org>
parents:
4786
diff
changeset
|
85 /* Eliminate signals whose signal handler is SIG_IGN. */ |
f64f1da7e350
Signals whose handler is set to SIG_IGN are not fatal.
Bruno Haible <bruno@clisp.org>
parents:
4786
diff
changeset
|
86 |
f64f1da7e350
Signals whose handler is set to SIG_IGN are not fatal.
Bruno Haible <bruno@clisp.org>
parents:
4786
diff
changeset
|
87 static void |
f64f1da7e350
Signals whose handler is set to SIG_IGN are not fatal.
Bruno Haible <bruno@clisp.org>
parents:
4786
diff
changeset
|
88 init_fatal_signals (void) |
f64f1da7e350
Signals whose handler is set to SIG_IGN are not fatal.
Bruno Haible <bruno@clisp.org>
parents:
4786
diff
changeset
|
89 { |
f64f1da7e350
Signals whose handler is set to SIG_IGN are not fatal.
Bruno Haible <bruno@clisp.org>
parents:
4786
diff
changeset
|
90 static bool fatal_signals_initialized = false; |
f64f1da7e350
Signals whose handler is set to SIG_IGN are not fatal.
Bruno Haible <bruno@clisp.org>
parents:
4786
diff
changeset
|
91 if (!fatal_signals_initialized) |
f64f1da7e350
Signals whose handler is set to SIG_IGN are not fatal.
Bruno Haible <bruno@clisp.org>
parents:
4786
diff
changeset
|
92 { |
5537
0fc3beabfb42
Portability fix: Don't assume sigaction(). (mingw doesn't have it.)
Bruno Haible <bruno@clisp.org>
parents:
5536
diff
changeset
|
93 #if HAVE_SIGACTION |
5536
f64f1da7e350
Signals whose handler is set to SIG_IGN are not fatal.
Bruno Haible <bruno@clisp.org>
parents:
4786
diff
changeset
|
94 size_t i; |
f64f1da7e350
Signals whose handler is set to SIG_IGN are not fatal.
Bruno Haible <bruno@clisp.org>
parents:
4786
diff
changeset
|
95 |
f64f1da7e350
Signals whose handler is set to SIG_IGN are not fatal.
Bruno Haible <bruno@clisp.org>
parents:
4786
diff
changeset
|
96 for (i = 0; i < num_fatal_signals; i++) |
f64f1da7e350
Signals whose handler is set to SIG_IGN are not fatal.
Bruno Haible <bruno@clisp.org>
parents:
4786
diff
changeset
|
97 { |
f64f1da7e350
Signals whose handler is set to SIG_IGN are not fatal.
Bruno Haible <bruno@clisp.org>
parents:
4786
diff
changeset
|
98 struct sigaction action; |
f64f1da7e350
Signals whose handler is set to SIG_IGN are not fatal.
Bruno Haible <bruno@clisp.org>
parents:
4786
diff
changeset
|
99 |
f64f1da7e350
Signals whose handler is set to SIG_IGN are not fatal.
Bruno Haible <bruno@clisp.org>
parents:
4786
diff
changeset
|
100 if (sigaction (fatal_signals[i], NULL, &action) >= 0 |
f64f1da7e350
Signals whose handler is set to SIG_IGN are not fatal.
Bruno Haible <bruno@clisp.org>
parents:
4786
diff
changeset
|
101 && action.sa_handler == SIG_IGN) |
f64f1da7e350
Signals whose handler is set to SIG_IGN are not fatal.
Bruno Haible <bruno@clisp.org>
parents:
4786
diff
changeset
|
102 fatal_signals[i] = -1; |
f64f1da7e350
Signals whose handler is set to SIG_IGN are not fatal.
Bruno Haible <bruno@clisp.org>
parents:
4786
diff
changeset
|
103 } |
5537
0fc3beabfb42
Portability fix: Don't assume sigaction(). (mingw doesn't have it.)
Bruno Haible <bruno@clisp.org>
parents:
5536
diff
changeset
|
104 #endif |
5536
f64f1da7e350
Signals whose handler is set to SIG_IGN are not fatal.
Bruno Haible <bruno@clisp.org>
parents:
4786
diff
changeset
|
105 |
f64f1da7e350
Signals whose handler is set to SIG_IGN are not fatal.
Bruno Haible <bruno@clisp.org>
parents:
4786
diff
changeset
|
106 fatal_signals_initialized = true; |
f64f1da7e350
Signals whose handler is set to SIG_IGN are not fatal.
Bruno Haible <bruno@clisp.org>
parents:
4786
diff
changeset
|
107 } |
f64f1da7e350
Signals whose handler is set to SIG_IGN are not fatal.
Bruno Haible <bruno@clisp.org>
parents:
4786
diff
changeset
|
108 } |
f64f1da7e350
Signals whose handler is set to SIG_IGN are not fatal.
Bruno Haible <bruno@clisp.org>
parents:
4786
diff
changeset
|
109 |
4770 | 110 |
111 /* ========================================================================= */ | |
112 | |
113 | |
4786
83d8d561903a
Improved 'fatal-signal' module.
Bruno Haible <bruno@clisp.org>
parents:
4770
diff
changeset
|
114 typedef void (*action_t) (void); |
83d8d561903a
Improved 'fatal-signal' module.
Bruno Haible <bruno@clisp.org>
parents:
4770
diff
changeset
|
115 |
83d8d561903a
Improved 'fatal-signal' module.
Bruno Haible <bruno@clisp.org>
parents:
4770
diff
changeset
|
116 /* Type of an entry in the actions array. |
83d8d561903a
Improved 'fatal-signal' module.
Bruno Haible <bruno@clisp.org>
parents:
4770
diff
changeset
|
117 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
|
118 therefore we mark it as 'volatile'. */ |
83d8d561903a
Improved 'fatal-signal' module.
Bruno Haible <bruno@clisp.org>
parents:
4770
diff
changeset
|
119 typedef struct |
83d8d561903a
Improved 'fatal-signal' module.
Bruno Haible <bruno@clisp.org>
parents:
4770
diff
changeset
|
120 { |
83d8d561903a
Improved 'fatal-signal' module.
Bruno Haible <bruno@clisp.org>
parents:
4770
diff
changeset
|
121 volatile action_t action; |
83d8d561903a
Improved 'fatal-signal' module.
Bruno Haible <bruno@clisp.org>
parents:
4770
diff
changeset
|
122 } |
83d8d561903a
Improved 'fatal-signal' module.
Bruno Haible <bruno@clisp.org>
parents:
4770
diff
changeset
|
123 actions_entry_t; |
83d8d561903a
Improved 'fatal-signal' module.
Bruno Haible <bruno@clisp.org>
parents:
4770
diff
changeset
|
124 |
4770 | 125 /* The registered cleanup actions. */ |
4786
83d8d561903a
Improved 'fatal-signal' module.
Bruno Haible <bruno@clisp.org>
parents:
4770
diff
changeset
|
126 static actions_entry_t static_actions[32]; |
83d8d561903a
Improved 'fatal-signal' module.
Bruno Haible <bruno@clisp.org>
parents:
4770
diff
changeset
|
127 static actions_entry_t * volatile actions = static_actions; |
83d8d561903a
Improved 'fatal-signal' module.
Bruno Haible <bruno@clisp.org>
parents:
4770
diff
changeset
|
128 static sig_atomic_t volatile actions_count = 0; |
4770 | 129 static size_t actions_allocated = SIZEOF (static_actions); |
130 | |
131 | |
132 /* Uninstall the handlers. */ | |
133 static inline void | |
134 uninstall_handlers () | |
135 { | |
136 size_t i; | |
137 | |
138 for (i = 0; i < num_fatal_signals; i++) | |
5536
f64f1da7e350
Signals whose handler is set to SIG_IGN are not fatal.
Bruno Haible <bruno@clisp.org>
parents:
4786
diff
changeset
|
139 if (fatal_signals[i] >= 0) |
f64f1da7e350
Signals whose handler is set to SIG_IGN are not fatal.
Bruno Haible <bruno@clisp.org>
parents:
4786
diff
changeset
|
140 signal (fatal_signals[i], SIG_DFL); |
4770 | 141 } |
142 | |
143 | |
144 /* The signal handler. It gets called asynchronously. */ | |
145 static void | |
146 fatal_signal_handler (int sig) | |
147 { | |
148 for (;;) | |
149 { | |
150 /* Get the last registered cleanup action, in a reentrant way. */ | |
151 action_t action; | |
152 size_t n = actions_count; | |
153 if (n == 0) | |
154 break; | |
155 n--; | |
156 actions_count = n; | |
4786
83d8d561903a
Improved 'fatal-signal' module.
Bruno Haible <bruno@clisp.org>
parents:
4770
diff
changeset
|
157 action = actions[n].action; |
4770 | 158 /* Execute the action. */ |
159 action (); | |
160 } | |
161 | |
4786
83d8d561903a
Improved 'fatal-signal' module.
Bruno Haible <bruno@clisp.org>
parents:
4770
diff
changeset
|
162 /* Now execute the signal's default action. |
83d8d561903a
Improved 'fatal-signal' module.
Bruno Haible <bruno@clisp.org>
parents:
4770
diff
changeset
|
163 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
|
164 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
|
165 handler returns; otherwise it is delivered already during raise(). */ |
4770 | 166 uninstall_handlers (); |
167 #if HAVE_RAISE | |
168 raise (sig); | |
169 #else | |
170 kill (getpid (), sig); | |
171 #endif | |
172 } | |
173 | |
174 | |
175 /* Install the handlers. */ | |
176 static inline void | |
177 install_handlers () | |
178 { | |
179 size_t i; | |
180 | |
181 for (i = 0; i < num_fatal_signals; i++) | |
5536
f64f1da7e350
Signals whose handler is set to SIG_IGN are not fatal.
Bruno Haible <bruno@clisp.org>
parents:
4786
diff
changeset
|
182 if (fatal_signals[i] >= 0) |
f64f1da7e350
Signals whose handler is set to SIG_IGN are not fatal.
Bruno Haible <bruno@clisp.org>
parents:
4786
diff
changeset
|
183 signal (fatal_signals[i], &fatal_signal_handler); |
4770 | 184 } |
185 | |
186 | |
187 /* Register a cleanup function to be executed when a catchable fatal signal | |
188 occurs. */ | |
189 void | |
190 at_fatal_signal (action_t action) | |
191 { | |
192 static bool cleanup_initialized = false; | |
193 if (!cleanup_initialized) | |
194 { | |
5536
f64f1da7e350
Signals whose handler is set to SIG_IGN are not fatal.
Bruno Haible <bruno@clisp.org>
parents:
4786
diff
changeset
|
195 init_fatal_signals (); |
4770 | 196 install_handlers (); |
197 cleanup_initialized = true; | |
198 } | |
199 | |
200 if (actions_count == actions_allocated) | |
201 { | |
202 /* Extend the actions array. Note that we cannot use xrealloc(), | |
203 because then the cleanup() function could access an already | |
204 deallocated array. */ | |
4786
83d8d561903a
Improved 'fatal-signal' module.
Bruno Haible <bruno@clisp.org>
parents:
4770
diff
changeset
|
205 actions_entry_t *old_actions = actions; |
4770 | 206 size_t new_actions_allocated = 2 * actions_allocated; |
4786
83d8d561903a
Improved 'fatal-signal' module.
Bruno Haible <bruno@clisp.org>
parents:
4770
diff
changeset
|
207 actions_entry_t *new_actions = |
83d8d561903a
Improved 'fatal-signal' module.
Bruno Haible <bruno@clisp.org>
parents:
4770
diff
changeset
|
208 xmalloc (new_actions_allocated * sizeof (actions_entry_t)); |
4770 | 209 |
4786
83d8d561903a
Improved 'fatal-signal' module.
Bruno Haible <bruno@clisp.org>
parents:
4770
diff
changeset
|
210 memcpy (new_actions, old_actions, |
83d8d561903a
Improved 'fatal-signal' module.
Bruno Haible <bruno@clisp.org>
parents:
4770
diff
changeset
|
211 actions_allocated * sizeof (actions_entry_t)); |
4770 | 212 actions = new_actions; |
213 actions_allocated = new_actions_allocated; | |
214 /* Now we can free the old actions array. */ | |
215 if (old_actions != static_actions) | |
216 free (old_actions); | |
217 } | |
4786
83d8d561903a
Improved 'fatal-signal' module.
Bruno Haible <bruno@clisp.org>
parents:
4770
diff
changeset
|
218 /* 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
|
219 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
|
220 the new action has been written to the memory location |
83d8d561903a
Improved 'fatal-signal' module.
Bruno Haible <bruno@clisp.org>
parents:
4770
diff
changeset
|
221 actions[actions_count]. */ |
83d8d561903a
Improved 'fatal-signal' module.
Bruno Haible <bruno@clisp.org>
parents:
4770
diff
changeset
|
222 actions[actions_count].action = action; |
4770 | 223 actions_count++; |
224 } | |
225 | |
226 | |
227 /* ========================================================================= */ | |
228 | |
229 | |
230 #if HAVE_POSIX_SIGNALBLOCKING | |
231 | |
232 static sigset_t fatal_signal_set; | |
233 | |
234 static void | |
235 init_fatal_signal_set () | |
236 { | |
237 static bool fatal_signal_set_initialized = false; | |
238 if (!fatal_signal_set_initialized) | |
239 { | |
240 size_t i; | |
241 | |
5536
f64f1da7e350
Signals whose handler is set to SIG_IGN are not fatal.
Bruno Haible <bruno@clisp.org>
parents:
4786
diff
changeset
|
242 init_fatal_signals (); |
f64f1da7e350
Signals whose handler is set to SIG_IGN are not fatal.
Bruno Haible <bruno@clisp.org>
parents:
4786
diff
changeset
|
243 |
4770 | 244 sigemptyset (&fatal_signal_set); |
245 for (i = 0; i < num_fatal_signals; i++) | |
5536
f64f1da7e350
Signals whose handler is set to SIG_IGN are not fatal.
Bruno Haible <bruno@clisp.org>
parents:
4786
diff
changeset
|
246 if (fatal_signals[i] >= 0) |
f64f1da7e350
Signals whose handler is set to SIG_IGN are not fatal.
Bruno Haible <bruno@clisp.org>
parents:
4786
diff
changeset
|
247 sigaddset (&fatal_signal_set, fatal_signals[i]); |
4770 | 248 |
249 fatal_signal_set_initialized = true; | |
250 } | |
251 } | |
252 | |
4786
83d8d561903a
Improved 'fatal-signal' module.
Bruno Haible <bruno@clisp.org>
parents:
4770
diff
changeset
|
253 /* Temporarily delay the catchable fatal signals. */ |
4770 | 254 void |
255 block_fatal_signals () | |
256 { | |
257 init_fatal_signal_set (); | |
258 sigprocmask (SIG_BLOCK, &fatal_signal_set, NULL); | |
259 } | |
260 | |
4786
83d8d561903a
Improved 'fatal-signal' module.
Bruno Haible <bruno@clisp.org>
parents:
4770
diff
changeset
|
261 /* Stop delaying the catchable fatal signals. */ |
4770 | 262 void |
263 unblock_fatal_signals () | |
264 { | |
265 init_fatal_signal_set (); | |
266 sigprocmask (SIG_UNBLOCK, &fatal_signal_set, NULL); | |
267 } | |
268 | |
269 #else | |
270 | |
271 /* Don't bother caring about the old systems which don't have POSIX signal | |
272 blocking. */ | |
273 | |
274 void | |
275 block_fatal_signals () | |
276 { | |
277 } | |
278 | |
279 void | |
280 unblock_fatal_signals () | |
281 { | |
282 } | |
283 | |
284 #endif |