118 pthread_mutex_lock(&lock);
119 if(atomic_compare_exchange_strong(&signal_nc, &expected, nc)){
121 sigaction(SIGWINCH, &old_winch,
NULL);
122 sigaction(SIGCONT, &old_cont,
NULL);
123 handling_winch =
false;
126 for(
unsigned i = 0 ; i <
sizeof(fatal_signals) /
sizeof(*fatal_signals) ; ++i){
127 sigaction(fatal_signals[i].sig, &fatal_signals[i].oldfxn,
NULL);
129 handling_fatals =
false;
131 if(alt_signal_stack.ss_sp){
132 alt_signal_stack.ss_flags = SS_DISABLE;
133 if(sigaltstack(&alt_signal_stack,
NULL)){
135 fprintf(stderr,
"couldn't remove alternate signal stack (%s)", strerror(errno));
139 *altstack = alt_signal_stack.ss_sp;
140 alt_signal_stack.ss_sp =
NULL;
141 ret = !atomic_compare_exchange_strong(&signal_nc, &expected,
NULL);
143 pthread_mutex_unlock(&lock);
145 fprintf(stderr,
"signals weren't registered for %p (had %p)", nc, expected);
170 invoke_old(&fatal_signals[i].oldfxn, signo, siginfo,
v);
193 int(*handler)(
void*,
void**,
int)){
195 void* expected =
NULL;
199 if(!atomic_compare_exchange_strong(&signal_nc, &expected, nc)){
200 fprintf(stderr,
"%p is already registered for signals (provided %p)" NL, expected, nc);
203 pthread_mutex_lock(&lock);
205 memset(&sa, 0,
sizeof(sa));
207 sigaddset(&sa.sa_mask, SIGWINCH);
208 sigaddset(&sa.sa_mask, SIGCONT);
210 ret |= sigaction(SIGWINCH, &sa, &old_winch);
211 ret |= sigaction(SIGCONT, &sa, &old_cont);
213 atomic_store(&signal_nc,
NULL);
214 pthread_mutex_unlock(&lock);
215 fprintf(stderr,
"error installing term signal handler (%s)" NL, strerror(errno));
220 pthread_sigmask(SIG_BLOCK, &sa.sa_mask,
NULL);
221 handling_winch =
true;
224 memset(&sa, 0,
sizeof(sa));
230 long minstksz = sysconf(_SC_SIGSTKSZ);
235 minstksz = SIGSTKSZ * 4;
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));
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;
248 sa.sa_flags = SA_ONSTACK;
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);
258 sa.sa_flags |= SA_SIGINFO | SA_RESETHAND;
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);
264 atomic_store(&signal_nc,
NULL);
265 pthread_mutex_unlock(&lock);
266 fprintf(stderr,
"error installing fatal signal handlers (%s)" NL, strerror(errno));
269 handling_fatals =
true;
273 sigaddset(&wblock_signals, SIGINT);
274 sigaddset(&wblock_signals, SIGTERM);
275 sigaddset(&wblock_signals, SIGQUIT);
276 pthread_mutex_unlock(&lock);
int setup_signals(void *vnc, bool no_quit_sigs, bool no_winch_sigs, int(*handler)(void *, void **, int))