内核线程中获取接收到的信号(二)
因此还是要从sys_sigpending()的实现中查找原因。
查看sys_sigpending()的
源码,只是对do_sigpending()函数的简单封装,继续从do_sigpending()中找原因。do_sigpending()源码如下:
[cpp] view plaincopy
long do_sigpending(void __user *set, unsigned long sigsetsize)
{
long error = -EINVAL;
sigset_t pending;
if (sigsetsize > sizeof(sigset_t))
goto out;
spin_lock_irq(¤t->sighand->siglock);
sigorsets(&pending, ¤t->pending.signal,
¤t->signal->shared_pending.signal);
spin_unlock_irq(¤t->sighand->siglock);
/* Outside the lock because only this thread touches it. */
sigandsets(&pending, ¤t->blocked, &pending);
error = -EFAULT;
if (!copy_to_user(set, &pending, sigsetsize))
error = 0;
out:
return error;
}
do_sigpending()首先调用sigorsets()将当前进程的信号信息(current->pending.signal和current->signal->shared_pending.signal)进行或操作(也就是将两个地方的信号掩码合并起来),存储在临时变量pending中。获取当前进程的信号掩码后,在传递到上层时,还要调用sigandsets()将pending和当前进程的信号掩码进行与操作后的结果就再传递到上层。
现在的问题就是要确定在调用sigandsets()之前pending的值和current->blocked的值。根据do_sigpending()来修改thread_process()函数,打印输出当前进程的信号位图和信号掩码,修改后的thread_process()函数如下所示:
[cpp] view plaincopy
static int thread_process(void *arg)
{
sigset_t *sigset, __sigset;
sigset = &__sigset;
allow_signal(SIGURG);
allow_signal(SIGTERM);
allow_signal(SIGKILL);
allow_signal(SIGSTOP);
allow_signal(SIGCONT);
printk(KERN_ALERT "the pid of thread_process is %d.\n", current->pid);
spin_lock_irq(¤t->sighand->siglock);
sigorsets(sigset, ¤t->pending.signal,
¤t->signal->shared_pending.signal);
spin_unlock_irq(¤t->sighand->siglock);
printk(KERN_ALERT "Before receive signal, signal map: 0x%lX.\n", sigset->sig[0]);
printk(KERN_ALERT "Beofore receive signal, blocked map: 0x%lX.\n", current->blocked.sig[0]);
for ( ; !remove_mod; ) {
/* Avoid infinite loop */
msleep(1000);
if (signal_pending(current)) {
spin_lock_irq(¤t->sighand->siglock);
sigorsets(sigset, ¤t->pending.signal,
¤t->signal->shared_pending.signal);
spin_unlock_irq(¤t->sighand->siglock);
printk(KERN_ALERT "Received signal, signal map: 0x%lX.\n", sigset->sig[0]);
printk(KERN_ALERT "Receive SIGURG signal %s.\n",
sigismember(sigset, SIGURG) "true" : "false");
printk(KERN_ALERT "Receive SIGTERM signal %s.\n",
sigismember(sigset, SIGTERM) "true" : "false");
printk(KERN_ALERT "Receive SIGKILL signal %s.\n",
sigismember(sigset, SIGKILL) "true" : "false");
printk(KERN_ALERT "Receive SIGSTOP signal %s.\n",
sigismember(sigset, SIGSTOP) "true" : "false");
/* Use halt to stop the system */
printk(KERN_ALERT "Receive SIGCONT signal %s.\n",
sigismember(sigset, SIGCONT) "true" : "false");
break;
}
}
return 0;
}
测试结果如下所示:
从蓝色的部分可以看出,current->bl