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