CPU architecture:ARM920T
Author:ce123(http://blog.csdn.net/ce123)
1.简介
如果进程要处理某一信号,那么要在进程中注册该信号。注册信号主要用来确定信号值及进程针对该信号值的动作之间的映射关系,即进程将要处理哪个进程和该信号被传递给进程时,将执行何种操作。主要有两个函数实现信号的注册:signal()和sigaction()。
2.signal()
signal()的函数原型如下:
- void (*signal(int signum, void (*handler)(int)))(int);
- #include
上述声明格式比较复杂,如果不清楚如何使用,也可以通过下面这种类型定义的格式来使用(POSIX的定义):
- typedef void (*sighandler_t)(int);
- sighandler_t signal(int signum, sighandler_t handler);
- SIG_IGN:忽略参数signum所指的信号。
- SIG_DFL:恢复参数signum所指信号的处理方法为默认值。
signal()通过系统调用sys_signal()为一个指定的信号设置用户态处理函数。sys_signal()定义如下:
- /*
- * For backwards compatibility. Functionality superseded by sigaction.
- */
- asmlinkage unsigned long
- sys_signal(int sig, __sighandler_t handler)
- {
- struct k_sigaction new_sa, old_sa;
- int ret;
- new_sa.sa.sa_handler = handler;
- new_sa.sa.sa_flags = SA_ONESHOT | SA_NOMASK;
- ret = do_sigaction(sig, &new_sa, &old_sa);
- return ret ? ret : (unsigned long)old_sa.sa.sa_handler;
- }
__sighandler_t的定义如下:
- typedef void __signalfn_t(int);
- typedef __signalfn_t __user *__sighandler_t;
信号由sys_signal()的第一个参数指定,信号处理函数的地址由第二个参数指定。sys_signal()根据这两个参数设置一个k_sigaction结构,然后调用do_sigaction(),该函数的定义我们会在后面具体讲解。
2.sigaction()
sigaction()的函数原型如下:
- sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
2.1do_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 = ¤tt->sighand->action[sig-1];
- spin_lock_irq(¤tt->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(¤tt->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(¤t->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(¤tt->sighand->siglock);
- return 0;
- }
上一篇:控制linux动态链接库导出函数
下一篇:linux内核中的信号机制--信号处理
推荐阅读最新更新时间:2024-03-16 14:45