int sigfillset (sigset_t *set) { if (set == NULL) { __set_errno (EINVAL); return -1; } memset (set, 0xff, sizeof (sigset_t)); /* If the implementation uses a cancellation signal don't set the bit. */ #ifdef SIGCANCEL __sigdelset (set, SIGCANCEL); #endif /* Likewise for the signal to implement setxid. */ #ifdef SIGSETXID __sigdelset (set, SIGSETXID); #endif #ifdef __CONFIG_RG_DBG_ULIBC_MALLOC__ /* Signall 59 used for debugging memory allocation */ __sigdelset(set, 59); #endif return 0; }
int pthread_sigmask (int how, const sigset_t *newmask, sigset_t *oldmask) { sigset_t local_newmask; /* The only thing we have to make sure here is that SIGCANCEL and SIGSETXID is not blocked. */ if (newmask != NULL && (__builtin_expect (__sigismember (newmask, SIGCANCEL), 0) || __builtin_expect (__sigismember (newmask, SIGSETXID), 0))) { local_newmask = *newmask; __sigdelset (&local_newmask, SIGCANCEL); __sigdelset (&local_newmask, SIGSETXID); newmask = &local_newmask; } #ifdef INTERNAL_SYSCALL /* We know that realtime signals are available if NPTL is used. */ INTERNAL_SYSCALL_DECL (err); int result = INTERNAL_SYSCALL (rt_sigprocmask, err, 4, how, newmask, oldmask, _NSIG / 8); return (INTERNAL_SYSCALL_ERROR_P (result, err) ? INTERNAL_SYSCALL_ERRNO (result, err) : 0); #else return sigprocmask (how, newmask, oldmask) == -1 ? errno : 0; #endif }
int sigprocmask(int how, const sigset_t * set, sigset_t * oldset) { #ifdef SIGCANCEL sigset_t local_newmask; /* * The only thing we have to make sure here is that SIGCANCEL and * SIGSETXID are not blocked. */ if (set != NULL && (__builtin_expect (__sigismember (set, SIGCANCEL), 0) # ifdef SIGSETXID || __builtin_expect (__sigismember (set, SIGSETXID), 0) # endif )) { local_newmask = *set; __sigdelset (&local_newmask, SIGCANCEL); # ifdef SIGSETXID __sigdelset (&local_newmask, SIGSETXID); # endif set = &local_newmask; } #endif return (__syscall_sigprocmask(how, set, oldset)); }
/* Return any pending signal or wait for one for the given time. */ static int do_sigwait (const sigset_t *set, int *sig) { int ret; #ifdef SIGCANCEL sigset_t tmpset; if (set != NULL && (__builtin_expect (__sigismember (set, SIGCANCEL), 0) # ifdef SIGSETXID || __builtin_expect (__sigismember (set, SIGSETXID), 0) # endif )) { /* Create a temporary mask without the bit for SIGCANCEL set. */ // We are not copying more than we have to. memcpy (&tmpset, set, _NSIG / 8); __sigdelset (&tmpset, SIGCANCEL); # ifdef SIGSETXID __sigdelset (&tmpset, SIGSETXID); # endif set = &tmpset; } #endif /* XXX The size argument hopefully will have to be changed to the real size of the user-level sigset_t. */ #ifdef INTERNAL_SYSCALL INTERNAL_SYSCALL_DECL (err); do ret = INTERNAL_SYSCALL (rt_sigtimedwait, err, 4, set, NULL, NULL, _NSIG / 8); while (INTERNAL_SYSCALL_ERROR_P (ret, err) && INTERNAL_SYSCALL_ERRNO (ret, err) == EINTR); if (! INTERNAL_SYSCALL_ERROR_P (ret, err)) { *sig = ret; ret = 0; } else ret = INTERNAL_SYSCALL_ERRNO (ret, err); #else do ret = INLINE_SYSCALL (rt_sigtimedwait, 4, set, NULL, NULL, _NSIG / 8); while (ret == -1 && errno == EINTR); if (ret != -1) { *sig = ret; ret = 0; } else ret = errno; #endif return ret; }
/* Clear a pending signal and return the associated detailed signal information. SS must be locked, and must have signal SIGNO pending, either directly or through the global sigstate. */ static struct hurd_signal_detail sigstate_clear_pending (struct hurd_sigstate *ss, int signo) { if (sigstate_is_global_rcv (ss) && __sigismember (&_hurd_global_sigstate->pending, signo)) { __sigdelset (&_hurd_global_sigstate->pending, signo); return _hurd_global_sigstate->pending_data[signo]; } assert (__sigismember (&ss->pending, signo)); __sigdelset (&ss->pending, signo); return ss->pending_data[signo]; }
int siginterrupt (int sig, int interrupt) { #ifdef SA_RESTART struct sigaction action; /* Fails if sig is bad. */ if (sigaction (sig, NULL, &action) < 0) return -1; if (interrupt) { __sigaddset (&_sigintr, sig); action.sa_flags &= ~SA_RESTART; } else { __sigdelset (&_sigintr, sig); action.sa_flags |= SA_RESTART; } return sigaction (sig, &action, NULL); #else __set_errno (ENOSYS); return -1; #endif }
/* If INTERRUPT is nonzero, make signal SIG interrupt system calls (causing them to fail with EINTR); if INTERRUPT is zero, make system calls be restarted after signal SIG. */ int siginterrupt (int sig, int interrupt) { #ifdef SA_RESTART extern sigset_t _sigintr attribute_hidden; /* Defined in signal.c. */ struct sigaction action; if (__sigaction (sig, (struct sigaction *) NULL, &action) < 0) return -1; if (interrupt) { __sigaddset (&_sigintr, sig); action.sa_flags &= ~SA_RESTART; } else { __sigdelset (&_sigintr, sig); action.sa_flags |= SA_RESTART; } if (__sigaction (sig, &action, (struct sigaction *) NULL) < 0) return -1; return 0; #else __set_errno (ENOSYS); return -1; #endif }
int sigdelset(sigset_t *__set, int __signo) { if (__signo == 0 || __signo >= _NSIG) { errno = EINVAL; return -1; } __sigdelset(__set, __signo); return 0; }
/* Run a specific sighandler from the top of the sigdata stack. The 'info' * struct is prepopulated before the call is triggered as the result of a * reflected fault. */ static void __run_sighandler() { struct pthread_tcb *me = pthread_self(); __sigdelset(&me->sigpending, me->sigdata->info.si_signo); trigger_posix_signal(me->sigdata->info.si_signo, &me->sigdata->info, &me->sigdata->u_ctx); uthread_yield(FALSE, __exit_sighandler_cb, 0); }
/* Add SIGNO to SET. */ int sigdelset (sigset_t *set, int signo) { if (set == NULL || signo <= 0 || signo >= NSIG) { __set_errno (EINVAL); return -1; } return __sigdelset (set, signo); }
/* Run through all pending sighandlers and trigger them with a NULL info field. * These handlers are triggered as the result of a pthread_kill(), and thus * don't require individual 'info' structs. */ static void __run_pending_sighandlers() { struct pthread_tcb *me = pthread_self(); sigset_t andset = me->sigpending & (~me->sigmask); for (int i = 1; i < _NSIG; i++) { if (__sigismember(&andset, i)) { __sigdelset(&me->sigpending, i); trigger_posix_signal(i, NULL, &me->sigdata->u_ctx); } } uthread_yield(FALSE, __exit_sighandler_cb, 0); }
/* Set all signals in SET. */ int sigfillset (sigset_t *set) { if (set == NULL) { __set_errno (EINVAL); return -1; } memset (set, 0xff, sizeof (sigset_t)); /* If the implementation uses a cancellation signal don't set the bit. */ #ifdef SIGCANCEL __sigdelset (set, SIGCANCEL); #endif /* Likewise for the signal to implement setxid. */ #ifdef SIGSETXID __sigdelset (set, SIGSETXID); #endif return 0; }
static int do_sigtimedwait (const sigset_t *set, siginfo_t *info, const struct timespec *timeout) { #ifdef SIGCANCEL sigset_t tmpset; if (set != NULL && (__builtin_expect (__sigismember (set, SIGCANCEL), 0) # ifdef SIGSETXID || __builtin_expect (__sigismember (set, SIGSETXID), 0) # endif )) { /* Create a temporary mask without the bit for SIGCANCEL set. */ // We are not copying more than we have to. memcpy (&tmpset, set, _NSIG / 8); __sigdelset (&tmpset, SIGCANCEL); # ifdef SIGSETXID __sigdelset (&tmpset, SIGSETXID); # endif set = &tmpset; } #endif /* XXX The size argument hopefully will have to be changed to the real size of the user-level sigset_t. */ int result = INLINE_SYSCALL (rt_sigtimedwait, 4, set, info, timeout, _NSIG / 8); /* The kernel generates a SI_TKILL code in si_code in case tkill is used. tkill is transparently used in raise(). Since having SI_TKILL as a code is useful in general we fold the results here. */ if (result != -1 && info != NULL && info->si_code == SI_TKILL) info->si_code = SI_USER; return result; }
static int __NC(sigwait)(const sigset_t *set, int *sig) { sigset_t tmp_mask; struct sigaction saved[NSIG]; struct sigaction action; int save_errno; int this; /* Prepare set. */ __sigfillset (&tmp_mask); /* Unblock all signals in the SET and register our nice handler. */ action.sa_handler = ignore_signal; action.sa_flags = 0; __sigfillset (&action.sa_mask); /* Block all signals for handler. */ /* Make sure we recognize error conditions by setting WAS_SIG to a value which does not describe a legal signal number. */ was_sig = -1; for (this = 1; this < NSIG; ++this) if (__sigismember (set, this)) { /* Unblock this signal. */ __sigdelset (&tmp_mask, this); /* Register temporary action handler. */ /* In Linux (as of 2.6.25), fails only if sig is SIGKILL or SIGSTOP */ /* (so, will it work correctly if set has, say, SIGSTOP?) */ if (sigaction (this, &action, &saved[this]) != 0) goto restore_handler; } /* Now we can wait for signals. */ __NC(sigsuspend)(&tmp_mask); restore_handler: save_errno = errno; while (--this >= 1) if (__sigismember (set, this)) /* We ignore errors here since we must restore all handlers. */ sigaction (this, &saved[this], NULL); __set_errno (save_errno); /* Store the result and return. */ *sig = was_sig; return was_sig == -1 ? -1 : 0; }
/* Set all signals in SET. */ int sigfillset (sigset_t *set) { #if 0 /* is it really required by standards?! */ if (set == NULL) { __set_errno (EINVAL); return -1; } #endif __sigfillset (set); /* If the implementation uses a cancellation signal don't set the bit. */ #ifdef SIGCANCEL __sigdelset (set, SIGCANCEL); #endif /* Likewise for the signal to implement setxid. */ #ifdef SIGSETXID __sigdelset (set, SIGSETXID); #endif return 0; }
/* Select any of pending signals from SET or wait for any to arrive. */ int __sigwait (const sigset_t *set, int *sig) { struct hurd_sigstate *ss; sigset_t mask, ready; int signo = 0; struct hurd_signal_preemptor preemptor; jmp_buf buf; mach_port_t wait; mach_msg_header_t msg; sighandler_t preempt_fun (struct hurd_signal_preemptor *pe, struct hurd_sigstate *ss, int *sigp, struct hurd_signal_detail *detail) { if (signo) /* We've already been run; don't interfere. */ return SIG_ERR; signo = *sigp; /* Make sure this is all kosher */ assert (__sigismember (&mask, signo)); /* Make sure this signal is unblocked */ __sigdelset (&ss->blocked, signo); return pe->handler; } void handler (int sig) { assert (sig == signo); longjmp (buf, 1); }