Mercurial > hg > octave-nkf > gnulib-hg
comparison lib/fatal-signal.c @ 10230:54813304edd2
Use sigaction module rather than signal().
* modules/c-stack (Depends-on): Add sigaction.
* modules/fatal-signal (Depends-on): Likewise.
* modules/nanosleep (Depends-on): Likewise.
* modules/sigprocmask (Files): Add sig-handler.h.
* modules/sigaction (Files): Likewise.
* lib/sig-handler.h (get_handler): New file, suggested by Paul
Eggert.
* lib/c-stack.c (SIGACTION_WORKS): Simplify conditions.
(c_stack_action) [!SIGACTION_WORKS]: Use sigaction, not signal.
* lib/fatal-signal.c (uninstall_handlers, install_handlers)
(init_fatal_signals): Likewise.
* lib/nanosleep.c (rpl_nanosleep): Likewise.
(siginterrupt): Delete fallback.
* lib/sigprocmask.c (handler_t): Delete.
(old_handlers): Use sa_handler_t instead.
* m4/nanosleep.m4 (gl_PREREQ_NANOSLEEP): Drop check for
siginterrupt.
Signed-off-by: Eric Blake <ebb9@byu.net>
author | Eric Blake <ebb9@byu.net> |
---|---|
date | Sat, 21 Jun 2008 07:08:49 -0600 |
parents | 8c0d36d59e97 |
children | 478a8cd21855 |
comparison
equal
deleted
inserted
replaced
10229:29502a2dd08a | 10230:54813304edd2 |
---|---|
24 #include <stdbool.h> | 24 #include <stdbool.h> |
25 #include <stdlib.h> | 25 #include <stdlib.h> |
26 #include <signal.h> | 26 #include <signal.h> |
27 #include <unistd.h> | 27 #include <unistd.h> |
28 | 28 |
29 #include "sig-handler.h" | |
29 #include "xalloc.h" | 30 #include "xalloc.h" |
30 | 31 |
31 #define SIZEOF(a) (sizeof(a) / sizeof(a[0])) | 32 #define SIZEOF(a) (sizeof(a) / sizeof(a[0])) |
32 | |
33 | 33 |
34 /* ========================================================================= */ | 34 /* ========================================================================= */ |
35 | 35 |
36 | 36 |
37 /* The list of fatal signals. | 37 /* The list of fatal signals. |
86 init_fatal_signals (void) | 86 init_fatal_signals (void) |
87 { | 87 { |
88 static bool fatal_signals_initialized = false; | 88 static bool fatal_signals_initialized = false; |
89 if (!fatal_signals_initialized) | 89 if (!fatal_signals_initialized) |
90 { | 90 { |
91 #if HAVE_SIGACTION | |
92 size_t i; | 91 size_t i; |
93 | 92 |
94 for (i = 0; i < num_fatal_signals; i++) | 93 for (i = 0; i < num_fatal_signals; i++) |
95 { | 94 { |
96 struct sigaction action; | 95 struct sigaction action; |
97 | 96 |
98 if (sigaction (fatal_signals[i], NULL, &action) >= 0 | 97 if (sigaction (fatal_signals[i], NULL, &action) >= 0 |
99 /* POSIX says that SIG_IGN can only occur when action.sa_flags | 98 && get_handler (&action) == SIG_IGN) |
100 does not contain SA_SIGINFO. But in Linux 2.4, for example, | |
101 SA_SIGINFO can actually be set and is ignored when sa_handler | |
102 is SIG_IGN. So don't bother testing for SA_SIGINFO. */ | |
103 && action.sa_handler == SIG_IGN) | |
104 fatal_signals[i] = -1; | 99 fatal_signals[i] = -1; |
105 } | 100 } |
106 #endif | |
107 | 101 |
108 fatal_signals_initialized = true; | 102 fatal_signals_initialized = true; |
109 } | 103 } |
110 } | 104 } |
111 | 105 |
134 /* Uninstall the handlers. */ | 128 /* Uninstall the handlers. */ |
135 static inline void | 129 static inline void |
136 uninstall_handlers () | 130 uninstall_handlers () |
137 { | 131 { |
138 size_t i; | 132 size_t i; |
139 | 133 struct sigaction action; |
134 | |
135 action.sa_handler = SIG_DFL; | |
136 action.sa_flags = 0; | |
137 sigemptyset (&action.sa_mask); | |
140 for (i = 0; i < num_fatal_signals; i++) | 138 for (i = 0; i < num_fatal_signals; i++) |
141 if (fatal_signals[i] >= 0) | 139 if (fatal_signals[i] >= 0) |
142 signal (fatal_signals[i], SIG_DFL); | 140 sigaction (fatal_signals[i], &action, NULL); |
143 } | 141 } |
144 | 142 |
145 | 143 |
146 /* The signal handler. It gets called asynchronously. */ | 144 /* The signal handler. It gets called asynchronously. */ |
147 static void | 145 static void |
160 /* Execute the action. */ | 158 /* Execute the action. */ |
161 action (); | 159 action (); |
162 } | 160 } |
163 | 161 |
164 /* Now execute the signal's default action. | 162 /* Now execute the signal's default action. |
165 If signal() blocks the signal being delivered for the duration of the | 163 If any cleanup action blocks the signal that triggered the cleanup, the |
166 signal handler's execution, the re-raised signal is delivered when this | 164 re-raised signal is delivered when this handler returns; otherwise it |
167 handler returns; otherwise it is delivered already during raise(). */ | 165 is delivered already during raise(). */ |
168 uninstall_handlers (); | 166 uninstall_handlers (); |
169 raise (sig); | 167 raise (sig); |
170 } | 168 } |
171 | 169 |
172 | 170 |
173 /* Install the handlers. */ | 171 /* Install the handlers. */ |
174 static inline void | 172 static inline void |
175 install_handlers () | 173 install_handlers () |
176 { | 174 { |
177 size_t i; | 175 size_t i; |
178 | 176 struct sigaction action; |
177 | |
178 action.sa_handler = &fatal_signal_handler; | |
179 /* One-shot handling - if we fault while handling a fault, the | |
180 cleanup actions are intentionally cut short. */ | |
181 action.sa_flags = SA_NODEFER | SA_RESETHAND; | |
182 sigemptyset (&action.sa_mask); | |
179 for (i = 0; i < num_fatal_signals; i++) | 183 for (i = 0; i < num_fatal_signals; i++) |
180 if (fatal_signals[i] >= 0) | 184 if (fatal_signals[i] >= 0) |
181 signal (fatal_signals[i], &fatal_signal_handler); | 185 sigaction (fatal_signals[i], &action, NULL); |
182 } | 186 } |
183 | 187 |
184 | 188 |
185 /* Register a cleanup function to be executed when a catchable fatal signal | 189 /* Register a cleanup function to be executed when a catchable fatal signal |
186 occurs. */ | 190 occurs. */ |