linux signal misc
在user space常使用的signal相关的API
1. 在user space注册信号处理函数
sigaction()函数prototype:
int sigaction(int signum, const struct sigaction *act,
struct sigaction *oldact);
struct sigaction sa_usr; sa_usr.sa_flags = 0; sa_usr.sa_handler = sig_usr; sigaction(SIGTERM, &sa_usr, NULL);
2. sigprocmask
这个系统调用是设置当前线程的task_struct.blocked阻塞signal集合,谁call的这个系统调用,就是设置谁的task_struct.blocked
操作有SIG_BLOCK/SIG_UNBLOCK/SIG_SETMASK,其含义分别为将task_struct.blocked对应bit或上/clear/直接整个赋值为新的block集合
在kernel space发送信号给user space进程
send_sig(int sig, struct task_struct *p, int priv)
sig即是signal num,比如SIGTERM,p是进程的task_struct,priv一般情况下传0即可
/proc/pid/status关于signal的部分
SigQ: 0/5319
SigPnd: 0000000000000000
ShdPnd: 0000000000000000
SigBlk: 0000000080000000 #此进程block的signal集合,如果某个bit为1,表示此进程block了此signal;如果为0表示没有block它
SigIgn: 0000000000000000 #此进程ignore的signal集合,如果某一个信号的sa_handler为SIG_IGN,表示此进程ignore此signal,这里打印出来的值为0,表示此进程没有ignore一个signal
SigCgt: 0000000c400084f8 #此进程会捕获的signal集合,如果某个bit为1,表示此进程注册了自己针对这个signal的信号处理函数;如果为0,表示没有注册自己的信号处理函数,即检查某个信号的处理函数sa_handler如果既不是SIG_IGN又不是SIG_DFL,则表示注册了自己的信号处理函数
static inline void task_sig(struct seq_file *m, struct task_struct *p) { unsigned long flags; sigset_t pending, shpending, blocked, ignored, caught; int num_threads = 0; unsigned int qsize = 0; unsigned long qlim = 0; sigemptyset(&pending); sigemptyset(&shpending); sigemptyset(&blocked); sigemptyset(&ignored); sigemptyset(&caught); if (lock_task_sighand(p, &flags)) { pending = p->pending.signal; shpending = p->signal->shared_pending.signal; blocked = p->blocked; collect_sigign_sigcatch(p, &ignored, &caught); num_threads = get_nr_threads(p); rcu_read_lock(); /* FIXME: is this correct? */ qsize = atomic_read(&__task_cred(p)->user->sigpending); rcu_read_unlock(); qlim = task_rlimit(p, RLIMIT_SIGPENDING); unlock_task_sighand(p, &flags); } seq_put_decimal_ull(m, "Threads:\t", num_threads); seq_put_decimal_ull(m, "\nSigQ:\t", qsize); seq_put_decimal_ull(m, "/", qlim); /* render them all */ render_sigset_t(m, "\nSigPnd:\t", &pending); render_sigset_t(m, "ShdPnd:\t", &shpending); render_sigset_t(m, "SigBlk:\t", &blocked); render_sigset_t(m, "SigIgn:\t", &ignored); render_sigset_t(m, "SigCgt:\t", &caught); }
static void collect_sigign_sigcatch(struct task_struct *p, sigset_t *ign, sigset_t *catch) { struct k_sigaction *k; int i; k = p->sighand->action; for (i = 1; i <= _NSIG; ++i, ++k) { if (k->sa.sa_handler == SIG_IGN) sigaddset(ign, i); else if (k->sa.sa_handler != SIG_DFL) sigaddset(catch, i); } }