分享

sigaction()

 皓月清风 2011-03-03

sigaction(查询或设置信号处理方式)
函数定义:int sigaction(int signum,const struct sigaction *act,struct sigaction *oldact);

表头文件:#include<signal.h>
函数说明:sigaction()会依参数signum指定的信号编号来设置该信号的处理函数。

1、参数signum可以指定SIGKILLSIGSTOP以外的所有信号。
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_DFLSIG_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

相关函数:signalsigprocmasksigpendingsigsuspend

 

例子:

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中去掉即可。

 

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多