Back to index

glibc  2.9
Functions
signals.c File Reference
#include <errno.h>
#include <signal.h>
#include "pthread.h"
#include "internals.h"
#include "spinlock.h"
#include <ucontext.h>

Go to the source code of this file.

Functions

int pthread_sigmask (int how, const sigset_t *newmask, sigset_t *oldmask)
int pthread_kill (pthread_t thread, int signo)
int __pthread_sigaction (int sig, const struct sigaction *act, struct sigaction *oact)
int __pthread_sigwait (const sigset_t *set, int *sig)
int __pthread_raise (int sig)
 LIBC_CANCEL_HANDLED ()

Function Documentation

Definition at line 198 of file signals.c.

{
  int retcode = pthread_kill(pthread_self(), sig);
  if (retcode == 0)
    return 0;
  else {
    errno = retcode;
    return -1;
  }
}

Here is the call graph for this function:

int __pthread_sigaction ( int  sig,
const struct sigaction act,
struct sigaction oact 
)

Definition at line 80 of file signals.c.

{
  struct sigaction newact;
  struct sigaction *newactp;
  __sighandler_t old = SIG_DFL;

  if (sig == __pthread_sig_restart ||
      sig == __pthread_sig_cancel ||
      (sig == __pthread_sig_debug && __pthread_sig_debug > 0))
    {
      __set_errno (EINVAL);
      return -1;
    }
  if (sig > 0 && sig < NSIG)
    old = (__sighandler_t) __sighandler[sig].old;
  if (act)
    {
      newact = *act;
      if (act->sa_handler != SIG_IGN && act->sa_handler != SIG_DFL
         && sig > 0 && sig < NSIG)
       {
         if (act->sa_flags & SA_SIGINFO)
           newact.sa_handler = (__sighandler_t) __pthread_sighandler_rt;
         else
           newact.sa_handler = (__sighandler_t) __pthread_sighandler;
         if (old == SIG_IGN || old == SIG_DFL || old == SIG_ERR)
           __sighandler[sig].old = (arch_sighandler_t) act->sa_handler;
       }
      newactp = &newact;
    }
  else
    newactp = NULL;
  if (__libc_sigaction(sig, newactp, oact) == -1)
    {
      if (act)
       __sighandler[sig].old = (arch_sighandler_t) old;
      return -1;
    }
  if (sig > 0 && sig < NSIG)
    {
      if (oact != NULL
         /* We may have inherited SIG_IGN from the parent, so return the
            kernel's idea of the signal handler the first time
            through.  */
         && old != SIG_ERR)
       oact->sa_handler = old;
      if (act)
       /* For the assignment it does not matter whether it's a normal
          or real-time signal.  */
       __sighandler[sig].old = (arch_sighandler_t) act->sa_handler;
    }
  return 0;
}

Here is the call graph for this function:

int __pthread_sigwait ( const sigset_t set,
int sig 
)

Definition at line 140 of file signals.c.

{
  volatile pthread_descr self = thread_self();
  sigset_t mask;
  int s;
  sigjmp_buf jmpbuf;
  struct sigaction sa;

  /* Get ready to block all signals except those in set
     and the cancellation signal.
     Also check that handlers are installed on all signals in set,
     and if not, install our dummy handler.  This is conformant to
     POSIX: "The effect of sigwait() on the signal actions for the
     signals in set is unspecified." */
  sigfillset(&mask);
  sigdelset(&mask, __pthread_sig_cancel);
  for (s = 1; s < NSIG; s++) {
    if (sigismember(set, s) &&
        s != __pthread_sig_restart &&
        s != __pthread_sig_cancel &&
        s != __pthread_sig_debug) {
      sigdelset(&mask, s);
      if (__sighandler[s].old == (arch_sighandler_t) SIG_ERR ||
          __sighandler[s].old == (arch_sighandler_t) SIG_DFL ||
          __sighandler[s].old == (arch_sighandler_t) SIG_IGN) {
        sa.sa_handler = __pthread_null_sighandler;
        sigfillset(&sa.sa_mask);
        sa.sa_flags = 0;
        sigaction(s, &sa, NULL);
      }
    }
  }
  /* Test for cancellation */
  if (sigsetjmp(jmpbuf, 1) == 0) {
    THREAD_SETMEM(self, p_cancel_jmp, &jmpbuf);
    if (! (THREAD_GETMEM(self, p_canceled)
          && THREAD_GETMEM(self, p_cancelstate) == PTHREAD_CANCEL_ENABLE)) {
      /* Reset the signal count */
      THREAD_SETMEM(self, p_signal, 0);
      /* Say we're in sigwait */
      THREAD_SETMEM(self, p_sigwaiting, 1);
      /* Unblock the signals and wait for them */
      sigsuspend(&mask);
    }
  }
  THREAD_SETMEM(self, p_cancel_jmp, NULL);
  /* The signals are now reblocked.  Check for cancellation */
  pthread_testcancel();
  /* We should have self->p_signal != 0 and equal to the signal received */
  *sig = THREAD_GETMEM(self, p_signal);
  return 0;
}

Here is the call graph for this function:

int pthread_kill ( pthread_t  thread,
int  signo 
)

Definition at line 57 of file signals.c.

{
  pthread_handle handle = thread_handle(thread);
  int pid;

  __pthread_lock(&handle->h_lock, NULL);
  if (invalid_handle(handle, thread)) {
    __pthread_unlock(&handle->h_lock);
    return ESRCH;
  }
  pid = handle->h_descr->p_pid;
  __pthread_unlock(&handle->h_lock);
  if (kill(pid, signo) == -1)
    return errno;
  else
    return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int pthread_sigmask ( int  how,
const sigset_t newmask,
sigset_t oldmask 
)

Definition at line 25 of file signals.c.

{
  sigset_t mask;

  if (newmask != NULL) {
    mask = *newmask;
    /* Don't allow __pthread_sig_restart to be unmasked.
       Don't allow __pthread_sig_cancel to be masked. */
    switch(how) {
    case SIG_SETMASK:
      sigaddset(&mask, __pthread_sig_restart);
      sigdelset(&mask, __pthread_sig_cancel);
      if (__pthread_sig_debug > 0)
       sigdelset(&mask, __pthread_sig_debug);
      break;
    case SIG_BLOCK:
      sigdelset(&mask, __pthread_sig_cancel);
      if (__pthread_sig_debug > 0)
       sigdelset(&mask, __pthread_sig_debug);
      break;
    case SIG_UNBLOCK:
      sigdelset(&mask, __pthread_sig_restart);
      break;
    }
    newmask = &mask;
  }
  if (sigprocmask(how, newmask, oldmask) == -1)
    return errno;
  else
    return 0;
}

Here is the call graph for this function: