196 {
198 void* expected =
NULL;
199 struct sigaction sa;
200
201
202 if(!atomic_compare_exchange_strong(&signal_nc, &expected, nc)){
203 fprintf(stderr, "%p is already registered for signals (provided %p)" NL, expected, nc);
204 return -1;
205 }
206 pthread_mutex_lock(&lock);
207 if(!no_winch_sigs){
208 memset(&sa, 0, sizeof(sa));
210 sigaddset(&sa.sa_mask, SIGWINCH);
211 sigaddset(&sa.sa_mask, SIGCONT);
212 int ret = 0;
213 ret |= sigaction(SIGWINCH, &sa, &old_winch);
214 ret |= sigaction(SIGCONT, &sa, &old_cont);
215 if(ret){
216 atomic_store(&signal_nc,
NULL);
217 pthread_mutex_unlock(&lock);
218 fprintf(stderr, "error installing term signal handler (%s)" NL, strerror(errno));
219 return -1;
220 }
221
222
223 pthread_sigmask(SIG_BLOCK, &sa.sa_mask,
NULL);
224 handling_winch = true;
225 }
226 if(!no_quit_sigs){
227 memset(&sa, 0, sizeof(sa));
228
229
230
231#ifndef USE_ASAN
232#ifdef _SC_SIGSTKSZ
233 long minstksz = sysconf(_SC_SIGSTKSZ);
234#else
235 long minstksz = 0;
236#endif
237 if(minstksz <= 0){
238 minstksz = SIGSTKSZ * 4;
239 }
240 alt_signal_stack.ss_sp = malloc(minstksz);
241 if(alt_signal_stack.ss_sp ==
NULL){
242 fprintf(stderr, "warning: couldn't create %ldB alternate signal stack (%s)" NL, minstksz, strerror(errno));
243 }else{
244 alt_signal_stack.ss_size = minstksz;
245 if(sigaltstack(&alt_signal_stack,
NULL)){
246 fprintf(stderr, "warning: couldn't set up %ldB alternate signal stack (%s)" NL, minstksz, strerror(errno));
247 free(alt_signal_stack.ss_sp);
248 alt_signal_stack.ss_sp =
NULL;
249 alt_signal_stack.ss_size = 0;
250 }else{
251 sa.sa_flags = SA_ONSTACK;
252 }
253 }
254#endif
255 fatal_callback = handler;
256 sa.sa_sigaction = fatal_handler;
257 sigaddset(&sa.sa_mask, SIGABRT);
258 sigaddset(&sa.sa_mask, SIGBUS);
259 sigaddset(&sa.sa_mask, SIGFPE);
260 sigaddset(&sa.sa_mask, SIGILL);
261 sigaddset(&sa.sa_mask, SIGINT);
262 sigaddset(&sa.sa_mask, SIGQUIT);
263 sigaddset(&sa.sa_mask, SIGSEGV);
264 sigaddset(&sa.sa_mask, SIGTERM);
265
266 sa.sa_flags |= SA_SIGINFO | SA_RESETHAND;
267 int ret = 0;
268 ret |= sigaction(SIGABRT, &sa, &old_abrt);
269 ret |= sigaction(SIGBUS, &sa, &old_bus);
270 ret |= sigaction(SIGFPE, &sa, &old_fpe);
271 ret |= sigaction(SIGILL, &sa, &old_ill);
272 ret |= sigaction(SIGINT, &sa, &old_int);
273 ret |= sigaction(SIGQUIT, &sa, &old_quit);
274 ret |= sigaction(SIGSEGV, &sa, &old_segv);
275 ret |= sigaction(SIGTERM, &sa, &old_term);
276 if(ret){
277 atomic_store(&signal_nc,
NULL);
278 pthread_mutex_unlock(&lock);
279 fprintf(stderr, "error installing fatal signal handlers (%s)" NL, strerror(errno));
280 return -1;
281 }
282 handling_fatals = true;
283 }
284
285
286 sigaddset(&wblock_signals, SIGINT);
287 sigaddset(&wblock_signals, SIGTERM);
288 sigaddset(&wblock_signals, SIGQUIT);
289 pthread_mutex_unlock(&lock);
290 return 0;
291}
void sigwinch_handler(int signo)