3、sigaction()

  sigaction()的函数原型如下:

sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);

  sigaction()对应的系统调用为do_sigaction(),下面我们具体讲解do_sigaction()函数,其定义如下:

  3.1 do_sigaction()

int
do_sigaction(int sig, const struct k_sigaction *act, struct k_sigaction *oact)
{
 struct k_sigaction *k;

 if (!valid_signal(sig) || sig < 1 || (act && sig_kernel_only(sig)))
  return -EINVAL;

 k = &currentt->sighand->action[sig-1];

 spin_lock_irq(&currentt->sighand->siglock);
 if (signal_pending(current)) {
  /*
   * If there might be a fatal signal pending on multiple
   * threads, make sure we take it before changing the action.
   */
  spin_unlock_irq(&currentt->sighand->siglock);
  return -ERESTARTNOINTR;
 }

 if (oact)//把原来的k_sigaction保存到oact结构中,这里是对整个数据结构进行复制
  *oact = *k;

 if (act) {
  /*
   * POSIX 3.3.1.3:
   *  "Setting a signal action to SIG_IGN for a signal that is
   *   pending shall cause the pending signal to be discarded,
   *   whether or not it is blocked."
   *
   *  "Setting a signal action to SIG_DFL for a signal that is
   *   pending and whose default action is to ignore the signal
   *   (for example, SIGCHLD), shall cause the pending signal to
   *   be discarded, whether or not it is blocked"
   */
  if (act->sa.sa_handler == SIG_IGN ||
      (act->sa.sa_handler == SIG_DFL &&
       sig_kernel_ignore(sig))) {
   /*
    * This is a fairly rare case, so we only take the
    * tasklist_lock once we're sure we'll need it.
    * Now we must do this little unlock and relock
    * dance to maintain the lock hierarchy.
    */
   struct task_struct *t = current;
   spin_unlock_irq(&t->sighand->siglock);
   read_lock(&tasklist_lock);
   spin_lock_irq(&t->sighand->siglock);
   *k = *act; //把新的k_sigaction结构复制到进程的sighand->action中

   sigdelsetmask(&k->sa.sa_mask,
          sigmask(SIGKILL) | sigmask(SIGSTOP));
   rm_from_queue(sigmask(sig), &t->signal->shared_pending);
   do {
    rm_from_queue(sigmask(sig), &t->pending);
    recalc_sigpending_tsk(t);
    t = next_thread(t);
   } while (t != current);
   spin_unlock_irq(&current->sighand->siglock);
   read_unlock(&tasklist_lock);
   return 0;
  }

  *k = *act; //把新的k_sigaction结构复制到进程的sighand->action中
  sigdelsetmask(&k->sa.sa_mask,
         sigmask(SIGKILL) | sigmask(SIGSTOP));
 }

 spin_unlock_irq(&currentt->sighand->siglock);
 return 0;