/* * If act is not NULL, set the action for signum. * If oact is not NULL. store the old action to oact. */ int sigaction(int signum, const struct sigaction *act, struct sigaction *oact) { struct sigaction *sa; if (signum <= 0 || signum >= NSIG || signum == SIGSTOP || signum == SIGKILL) { errno = EINVAL; return -1; } SIGNAL_LOCK(); sa = &__sig_act[signum]; if (oact != NULL) *oact = *sa; if (act != NULL) *sa = *act; /* Discard pending signal in some cases */ if (sa->sa_handler == SIG_IGN || (sa->sa_handler == SIG_DFL && signum == SIGCHLD)) __sig_pending &= ~sigmask(signum); SIGNAL_UNLOCK(); /* Process pending signal */ __sig_flush(); return 0; }
/* * Exception handler for signal emulation */ static void __exception_handler(int excpt) { if (excpt > 0 && excpt <= NSIG) { SIGNAL_LOCK(); if (__sig_act[excpt].sa_handler != SIG_IGN) __sig_pending |= sigmask(excpt); SIGNAL_UNLOCK(); } __sig_flush(); exception_return(); }
int pause(void) { int sig, wait; /* Wait signal if no pending singal */ if (__sig_flush()) { wait = 1; while (wait) { exception_wait(&sig); SIGNAL_LOCK(); /* It is ok if processed signal is not masked and not pending */ if (!(__sig_mask & sigmask(sig)) && !(__sig_pending & sigmask(sig))) wait = 0; SIGNAL_UNLOCK(); } } /* Always returns error */ errno = EINTR; return -1; }