sigaction(查询或设置信号处理方式)
函数定义:int sigaction(int signum,const struct sigaction *act,struct sigaction *oldact);
表头文件:#include<signal.h>
函数说明:sigaction()会依参数signum指定的信号编号来设置该信号的处理函数。
1、参数signum可以指定SIGKILL和SIGSTOP以外的所有信号。
2、参数结构sigaction定义如下:
struct sigaction
{
void (*sa_handler) ();
void (*sa_sigaction)(int signo, siginfo_t* info, void* other);
sigset_t sa_mask;
int sa_flags;
}
(1) 选择 sa_handler 还是 sa_sigaction
首先,要在老的信号处理方式和新的更强大的信号处理方式之间作出选择。如果老的处理方式(即SIG_DFL、SIG_IGN 后者处理函数)就够用了,那么可以设置 sa_handler 为其中之一。当然,如果指定为旧的信号处理方式,那么只能得到信号编号。否则,如果设定 sa_sigaction 为一个处理函数,那么这个处理函数被调用的时候,不但可以得到信号编号,而且可以获悉被调用的原因以及产生问题的上下文的相关信息。两者之间的差异总结如下:
使用旧的处理机制:struct sigaction action; action.sa_handler=handler_old;
使用新的处理机制:struct sigaction action; action.sa_sigaction=handler_new;
如何告诉内核你使用的是新的信号处理方式?很简单,只需设置 sa_flags 的 SA_SIGINFO 位。
(2) sa_mask 决定在处理一个消息时是否要阻塞其他信号。
(3) sa_flags 用一些位来设置信号处理的其他相关操作。
3、如果参数oldact不是NULL指针,则原来的信号处理方式会由此结构sigaction 返回。
返回值:执行成功则返回0,如果有错误则返回-1。
相关函数:signal,sigprocmask,sigpending,sigsuspend
例子:
void inthandler(int s) //s=2,为SIGINT对应的值
{
printf("Called with signal %d\n",s);
sleep(s);
printf("done handling signal %d\n",s);
}
void main()
{
char x[100];
struct sigaction handler;
sigset_t blocked;
handler.sa_handler = inthandler;
handler.sa_flags = SA_RESETHAND; //Reset handler to SIG_DFL when handling signal
sigemptyset(&blocked);
sigaddset(&blocked, SIGQUIT);
handler.sa_mask = blocked;
if (sigaction(SIGINT, &handler, NULL) == -1)
perror("sigaction");
else
while(1)
{
fgets(x,100,stdin);
printf("input: %s",x);
}
}
试着运行这个程序。如果以很快的速度连续按 Ctrl-C 和 Ctrl-\,退出信号将被阻塞直到中断信号处理完毕。如果连续按两下 Ctrl-C,进程就将被第二个信号杀死。如果想要捕获所有 Ctrl-C,将 SA_RESETHAND 掩码从 sa_flags中去掉即可。
联系客服