Linux内核中的信号机制--从用户层到内核层

发表于:2013-2-26 10:00

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:ce123    来源:51Testing软件测试网采编

分享:

  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;
}

相关链接:

Linux内核中的信号机制——一个简单的例子

Linux内核中的信号机制——信号发送

Linux内核中的信号机制——信号处理

22/2<12
价值129的会员专享直播免费赠送,添加微信领取听课名额哦~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计

法律顾问:上海漕溪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2023
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号