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. */