action.sa_handler = __pthread_sighandler; sigemptyset(&action.sa_mask); action.sa_flags = 0; sigaction(s, &action, &(saved_signals[s])); sigaddset(&sigwaited, s); }
int sigwait(const sigset_t * set, int * sig){  volatile pthread_descr self = thread_self();  sigset_t mask;  int s;  struct sigaction action, saved_signals[NSIG];  sigjmp_buf jmpbuf;  pthread_mutex_lock(&sigwaited_mut);  /* Make sure no other thread is waiting on our signals */test_again:  for (s = 1; s < NSIG; s++) {    if (sigismember(set, s) && sigismember(&sigwaited, s)) {      pthread_cond_wait(&sigwaited_changed, &sigwaited_mut);      goto test_again;    }  }  /* Get ready to block all signals except those in set     and the cancellation signal */  sigfillset(&mask);  sigdelset(&mask, PTHREAD_SIG_CANCEL);  /* Signals in set are assumed blocked on entrance */  /* Install our signal handler on all signals in set,     and unblock them in mask.     Also mark those signals as being sigwaited on */  for (s = 1; s < NSIG; s++) {    if (sigismember(set, s) && s != PTHREAD_SIG_CANCEL) {      sigdelset(&mask, s);      action.sa_handler = __pthread_sighandler;      sigemptyset(&action.sa_mask);      action.sa_flags = 0;      sigaction(s, &action, &(saved_signals[s]));      sigaddset(&sigwaited, s);    }  }  pthread_mutex_unlock(&sigwaited_mut);  /* Test for cancellation */  if (sigsetjmp(jmpbuf, 1) == 0) {    self->p_cancel_jmp = &jmpbuf;    if (! (self->p_canceled && self->p_cancelstate == PTHREAD_CANCEL_ENABLE)) {      /* Reset the signal count */      self->p_signal = 0;      /* Unblock the signals and wait for them */      sigsuspend(&mask);    }  }  self->p_cancel_jmp = NULL;  /* The signals are now reblocked. Restore the sighandlers. */  pthread_mutex_lock(&sigwaited_mut);  for (s = 1; s < NSIG; s++) {    if (sigismember(set, s) && s != PTHREAD_SIG_CANCEL) {      sigaction(s, &(saved_signals[s]), NULL);      sigdelset(&sigwaited, s);    }  }  pthread_cond_broadcast(&sigwaited_changed);  pthread_mutex_unlock(&sigwaited_mut);  /* Check for cancellation */  pthread_testcancel();  /* We should have self->p_signal != 0 and equal to the signal received */  *sig = self->p_signal;  return 0;}