static int efab_signal_handler_type(int sig, __sighandler_t user_handler) { if( user_handler == SIG_IGN ) return OO_SIGHANGLER_IGN_BIT; else if( user_handler != SIG_DFL ) return OO_SIGHANGLER_USER; else if( sig_kernel_stop(sig) ) return OO_SIGHANGLER_STOP; else if( sig_kernel_coredump(sig) ) return OO_SIGHANGLER_CORE; else if( sig_kernel_ignore(sig) ) return OO_SIGHANGLER_IGN_BIT; else return OO_SIGHANGLER_TERM; }
static inline int sig_ignored(struct task_struct *t, int sig) { void * handler; /* * Tracers always want to know about signals.. */ if (t->ptrace & PT_PTRACED) return 0; /* * Blocked signals are never ignored, since the * signal handler may change by the time it is * unblocked. */ if (sigismember(&t->blocked, sig)) return 0; /* Is it explicitly or implicitly ignored? */ handler = t->sighand->action[sig-1].sa.sa_handler; return handler == SIG_IGN || (handler == SIG_DFL && sig_kernel_ignore(sig)); }
static int efab_signal_do_sigaction(int sig, struct sigaction *act, struct sigaction *oact, struct mm_signal_data *tramp_data, int *out_pass_to_kernel) { int rc = 0; if( !valid_signal(sig) || sig < 1 || (act != NULL && sig_kernel_only(sig)) ) return -EINVAL; if( oact != NULL ) { rc = efab_signal_report_sigaction(sig, oact, tramp_data); if( rc != 0 ) return rc; } if( act != NULL ) { sigdelsetmask(&act->sa_mask, sigmask(SIGKILL) | sigmask(SIGSTOP)); /* If the signal is ignored now, we should ignore all already-pending * signals. Instead of doing it, pass this to OS. */ if( act->sa_handler == SIG_IGN || (act->sa_handler == SIG_DFL && sig_kernel_ignore(sig)) ) *out_pass_to_kernel = 1; else if( act->sa_flags & SA_ONSTACK && !tramp_data->sa_onstack_intercept ) *out_pass_to_kernel = 1; else rc = efab_signal_substitute(sig, act, tramp_data); } else efab_signal_recheck(sig, tramp_data); return rc; }