本文主要参考《unix环境高级编程》
 
sigaction函数的功能是检查或修改与指定信号相关联的处理动作(可同时两种操作)。
 

int sigaction(int signo,const struct sigaction *restrict act,

              struct sigaction *restrict oact);

结构sigaction定义如下:

struct sigaction{
  void (*sa_handler)(int);
  sigset_t sa_mask;
  int sa_flag;
  void (*sa_sigaction)(int,siginfo_t *,void *);
};

sa_handler字段包含一个信号捕捉函数的地址

sa_mask字段说明了一个信号集,在调用该信号捕捉函数之前,这一信号集要加进进程的信号屏蔽字中。仅当从信号捕捉函数返回时再将进程的信号屏蔽字复位为原先值。

sa_flag是一个选项,主要理解两个

SA_INTERRUPT 由此信号中断的系统调用不会自动重启
SA_RESTART 由此信号中断的系统调用会自动重启

SA_SIGINFO 提供附加信息,一个指向siginfo结构的指针以及一个指向进程上下文标识符的指针

最后一个参数是一个替代的信号处理程序,当设置SA_SIGINFO时才会用他,具体有些烦,暂时用不到,不看了。

下面的代码是用sigaction实现signal函数:

 

#include "apue.h"
Sigfunc *signal(int signo,Sigfunc *func)
{
  struct sigaction act;//新的信号关联信息

struct sigaction oact;//老的信号关联信息

act.sa_handler = func;//新的信号处理函数

sigemptyset(&act.sa_mask);//初始化屏蔽字

act.sa_flags = 0;//初始化flags

if (signo == SIGALRM) {//不会重启动
#ifdef SA_INTERRUPT
     act.sa_flags |= SA_INERRUPT;
#endif
  } else { //重启动
#ifdef SA_RESTART
     act.sa_flags |= SA_RESTART;
#endif
  }
  if (sigaction(signo, &act, &oact) < 0)//新老交换
      return(SIG_ERR);
   return (oact.sa_handler);
}

 
 
信号安装函数sigaction(int signum,const struct sigaction *act,struct sigaction *oldact)的第二个参数是一个指向sigaction结构的指针(结构体名称与函数名一样,千万别弄混淆了)。在结构sigaction的实例中,指定了对特定信号的处理,信号所传递的信息,信号处理函数执行过程中应屏蔽掉哪些函数等。当然,此指针也可以为NULL,进程会以默认方式处理信号。以下就简单介绍一下sigaction结构以及一般的用法。
        对于内核头文件而言,struct sigaction 结构体定义在kernel/include/asm/signal.h,此头文件又被kernel/include/linux/signal.h包含。
        对于用户空间的头文件而言,struct sigaction定义在 /usr/include/bits/sigaction.h,此头文件又被/usr/include/signal.h包含,所以应用程序中如果用到此结构,只要#include <signal.h>即可。注意内核中的定义和应用程序中的定义是不一样的,内核空间的sigaction结构只支持函数类型为 __sighandler_t的信号处理函数,不能处理信号传递的额外信息。具体定义如下:
……
/* Type of a signal handler.   */
typedef void (*__sighandler_t)(int);
……
#ifdef __KERNEL__
struct old_sigaction {
          __sighandler_t sa_handler;
         old_sigset_t sa_mask;
         unsigned long sa_flags;
         void (*sa_restorer)(void);
};
struct sigaction {
         __sighandler_t sa_handler;
        unsigned long sa_flags;
        void (*sa_restorer)(void);
        sigset_t sa_mask;   /* mask last for extensibility */
};
struct k_sigaction {
        struct sigaction sa;
};
#else
/* Here we must cater to libcs that poke about in kernel headers.   */
struct sigaction {
          union {
                  __sighandler_t _sa_handler;
                  void (*_sa_sigaction)(int, struct siginfo *, void *);
          } _u;
          sigset_t sa_mask;
          unsigned long sa_flags;
          void (*sa_restorer)(void);
};
#define sa_handler   _u._sa_handler
#define sa_sigaction _u._sa_sigaction
#endif /* __KERNEL__ */
sa_handler的原型是一个参数为int,返回类型为void的函数指针。参数即为信号值,所以信号不能传递除信号值之外的任何信息;
sa_sigaction的原型是一个带三个参数,类型分别为int,struct siginfo *,void *,返回类型为void的函数指针。第一个参数为信号值;第二个参数是一个指向struct siginfo结构的指针,此结构中包含信号携带的数据值;第三个参数没有使用。
sa_mask指定在信号处理程序执行过程中,哪些信号应当被阻塞。默认当前信号本身被阻塞。
sa_flags包含了许多标志位,比较重要的一个是SA_SIGINFO,当设定了该标志位时,表示信号附带的参数可以传递到信号处理函数中。即使sa_sigaction指定信号处理函数,如果不设置SA_SIGINFO,信号处理函数同样不能得到信号传递过来的数据,在信号处理函数中对这些信息的访问都将导致段错误。
sa_restorer已过时,POSIX不支持它,不应再使用。
        因此,当你的信号需要接收附加信息的时候,你必须给sa_sigaction赋信号处理函数指针,同时还要给sa_flags赋SA_SIGINFO,类似下面的代码:
     #include <signal.h>
     ……
     void sig_handler_with_arg(int sig,siginfo_t *sig_info,void *unused){……}
    
     int main(int argc,char **argv)
     {
              struct sigaction sig_act;
              ……
              sigemptyset(&sig_act.sa_mask);
              sig_act.sa_sigaction=sig_handler_with_arg;
              sig_act.sa_flags=SA_SIGINFO;
  
               ……
     }
        如果你的应用程序只需要接收信号,而不需要接收额外信息,那你需要的设置的是sa_handler,而不是sa_sigaction,你的程序可能类似下面的代码:
     #include <signal.h>
     ……
     void sig_handler(int sig){……}
    
     int main(int argc,char **argv)
     {
              struct sigaction sig_act;
              ……
              sigemptyset(&sig_act.sa_mask);
              sig_act.sa_handler=sig_handler;
              sig_act.sa_flags=0;
  
               ……
      }
      如果需要更详细说明,请参阅sigaction的man手册。
补充:
简而言之就是:
//自定义退出函数
    sigact.sa_handler = mysighandler;
    sigemptyset(&sigact.sa_mask);
    sigact.sa_flags = 0;
    sigaction(SIGINT, &sigact, NULL);
    sigaction(SIGTERM, &sigact, NULL);
    sigaction(SIGQUIT, &sigact, NULL);
 
或者利用signal函数进行信号捕捉:
void (*signal(int signo, void (*handler)(int)))(int);
 
当signal到来时,程序运行某函数,函数由你自己指定。
 
附带各种信号定义:
在终端使用kill -l 命令可以显示所有的信号。
$kill -l
1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL
5) SIGTRAP 6) SIGABRT 7) SIGBUS 8) SIGFPE
9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR2
13) SIGPIPE 14) SIGALRM 15) SIGTERM 16) SIGSTKFLT
17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP
21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU
25) SIGXFSZ 26) SIGVTALRM 27) SIGPROF 28) SIGWINCH
29) SIGIO 30) SIGPWR 31) SIGSYS 34) SIGRTMIN
35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3 38) SIGRTMIN+4
39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8
43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12
47) SIGRTMIN+13 48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14
51) SIGRTMAX-13 52) SIGRTMAX-12 53) SIGRTMAX-11 54) SIGRTMAX-10
55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7 58) SIGRTMAX-6
59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2
63) SIGRTMAX-1 64) SIGRTMAX
其中前面31个信号为不可靠信号(非实时的,可能会出现信号的丢失),后面的信号为可靠信号(实时的real_time,对信号
排队,不会丢失)。
1) SIGHUP (挂起) 当运行进程的用户注销时通知该进程,使进程终止
2) SIGINT (中断) 当用户按下时,通知前台进程组终止进程
3) SIGQUIT (退出) 用户按下或时通知进程,使进程终止
4) SIGILL (非法指令) 执行了非法指令,如可执行文件本身出现错误、试图执行数据段、堆栈溢出
5) SIGTRAP 由断点指令或其它trap指令产生. 由debugger使用
6) SIGABRT (异常中止) 调用abort函数生成的信号
7) SIGBUS 非法地址, 包括内存地址对齐(alignment)出错. eg: 访问一个四个字长的整数, 但其地址不是4的倍数.
8) SIGFPE (算术异常) 发生致命算术运算错误,包括浮点运算错误、溢出及除数为0.
9) SIGKILL (确认杀死) 当用户通过kill -9命令向进程发送信号时,可靠的终止进程
10) SIGUSR1 用户使用
11) SIGSEGV (段越界) 当进程尝试访问不属于自己的内存空间导致内存错误时,终止进程
12) SIGUSR2 用户使用
13) SIGPIPE 写至无读进程的管道, 或者Socket通信SOCT_STREAM的读进程已经终止,而再写入。
14) SIGALRM (超时) alarm函数使用该信号,时钟定时器超时响应
15) SIGTERM (软中断) 使用不带参数的kill命令时终止进程
17) SIGCHLD (子进程结束) 当子进程终止时通知父进程
18) SIGCONT (暂停进程继续) 让一个停止(stopped)的进程继续执行. 本信号不能被阻塞.
19) SIGSTOP (停止) 作业控制信号,暂停停止(stopped)进程的执行. 本信号不能被阻塞, 处理或忽略.
20) SIGTSTP (暂停/停止) 交互式停止信号, Ctrl-Z 发出这个信号
21) SIGTTIN 当后台作业要从用户终端读数据时, 终端驱动程序产生SIGTTIN信号
22) SIGTTOU 当后台作业要往用户终端写数据时, 终端驱动程序产生SIGTTOU信号
23) SIGURG 有"紧急"数据或网络上带外数据到达socket时产生.
24) SIGXCPU 超过CPU时间资源限制. 这个限制可以由getrlimit/setrlimit来读取/改变。
25) SIGXFSZ 当进程企图扩大文件以至于超过文件大小资源限制。
26) SIGVTALRM 虚拟时钟信号. 类似于SIGALRM, 但是计算的是该进程占用的CPU时间.
27) SIGPROF (梗概时间超时) setitimer(2)函数设置的梗概统计间隔计时器(profiling interval timer)
28) SIGWINCH 窗口大小改变时发出.
29) SIGIO(异步I/O) 文件描述符准备就绪, 可以开始进行输入/输出操作.
30) SIGPWR 电源失效/重启动
31) SIGSYS 非法的系统调用。
在以上列出的信号中,
程序不可捕获、阻塞或忽略的信号有:SIGKILL,SIGSTOP
不能恢复至默认动作的信号有:SIGILL,SIGTRAP
默认会导致进程流产的信号有:SIGABRT,SIGBUS,SIGFPE,SIGILL,SIGIOT,SIGQUIT,SIGSEGV,SIGTRAP,SIGXCPU,SIGXFSZ
默认会导致进程退出的信号有:SIGALRM,SIGHUP,SIGINT,SIGKILL,SIGPIPE,SIGPOLL,SIGPROF,SIGSYS,SIGTERM,SIGUSR1,SIGUSR2,SIGVTALRM
默认会导致进程停止的信号有:SIGSTOP,SIGTSTP,SIGTTIN,SIGTTOU
默认进程忽略的信号有:SIGCHLD,SIGPWR,SIGURG,SIGWINCH
此外,SIGIO在SVR4是退出,在4.3BSD中是忽略;SIGCONT在进程挂起时是继续,否则是忽略,不能被阻塞。
 
在Unix/Linux中signal函数是比较复杂的一个,其定义原型如下:
void (*signal(int signo,void (*func)(int))) (int)
这个函数中,最外层的函数体
void (* XXX )(int)表明是一个指针,指向一个函数XXX的指针,XXX所代表的函数需要一个int型的参数,返回void
signal(int signo, void(*func)(int))是signal函数的主体.
需要两个参数int型的signo以及一个指向函数的函数.
void (*func)(int).
正是由于其复杂性,在[Plauger 1992]用typedef来对其进行简化
typedef void Sigfuc(int);//这里可以看成一个返回值 .
再对signal函数进行简化就是这样的了
Sigfunc *signal(int,Sigfuc *);
 
在signal.h头文件中还有以下几个定义
#define SIG_ERR (void (*)())-1
#define SIG_DFL (void (*)())0
#define SIG_IGN (void (*)())1
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/lanmanck/archive/2009/09/19/4568911.aspx

sigaction 函数的更多相关文章

  1. Linux C--信号 sigaction函数

    使用 sigaction 函数: signal 函数的使用方法简单,但并不属于 POSIX 标准,在各类 UNIX 平台上的实现不尽相同,因此其用途受 到了一定的限制.而 POSIX 标准定义的信号处 ...

  2. Linux 信号(三)—— sigaction 函数

    ilocker:关注 Android 安全(新入行,0基础) QQ: 2597294287 #include <signal.h> int sigaction(int signo, con ...

  3. 信号之sigaction函数

    sigaction函数的功能是检查或修改与指定信号相关联的处理动作(或同时执行这两种操作). #include <signal.h> int sigaction( int signo, c ...

  4. signal函数、sigaction函数及信号集(sigemptyset,sigaddset)操作函数

    信号是与一定的进程相联系的.也就是说,一个进程可以决定在进程中对哪些信号进行什 么样的处理.例如,一个进程可以忽略某些信号而只处理其他一些信号:另外,一个进程还可以选择如何处理信号.总之,这些总与特定 ...

  5. sigaction函数的使用

    sigaction函数的功能是检查或修改与指定信号相关联的处理动作(可同时两种操作). 他是POSIX的信号接口,而signal()是标准C的信号接口(如果程序必须在非POSIX系统上运行,那么就应该 ...

  6. sigaction函数解析

    http://blog.chinaunix.net/uid-1877180-id-3011232.html sigaction函数解析  sigaction函数的功能是检查或修改与指定信号相关联的处理 ...

  7. 《UNIX环境高级编程》笔记--sigaction函数

    sigaction函数的功能是检查或修改指定信号相关联的处理动作,此函数取代UNIX早期版本使用的signal函数. #include<signal.h> int sigaction(in ...

  8. 使用sigaction函数

    sigaction函数 修改信号处理动作(通常在Linux用其来注册一个信号的捕捉函数) :失败:-1,设置errno 参数: act:传入参数,新的处理方式.oldact:传出参数,旧的处理方式. ...

  9. UNIX环境编程学习笔记(25)——信号处理进阶学习之 sigaction 函数

    lienhua342014-11-05 sigaction 函数跟 signal 函数一样,用于设置信号处理函数.此函数是用于取代 UNIX 早期版本使用的 signal 函数.UNIX 早期版本的 ...

随机推荐

  1. ASP.NET MVC5学习笔记之Filter提供体系

    前面我们介绍了Filter的基本使用,但各种Filter要在合适的时机运行起来,需要预先准备好,现在看看ASP.NET MVC框架是怎么做的. 一.Filter集合 在ControlerActionI ...

  2. 配置《算法 第四版》的Eclipse开发环境

    1. 安装JAVA JAVA网址:http://www.oracle.com/technetwork/java/javase/downloads/index.html 配置环境变量(我把JAVA安装在 ...

  3. jruby中的异常

    先看看ruby中的异常知识: 异常处理raise 例子: raise raise "you lose" raise SyntaxError.new("invalid sy ...

  4. 【PHP】PHP中的类与对象

    面向对象并不是PHP的关键,但PHP确实能很好的支持面向对象编程,而且类与对象也成为了PHP5的核心组成部分.PHP的面向对象特性让构建大型的复制应用成为可能,有了类与对象,就自然产生了各种编程范式和 ...

  5. Android UI效果实现——Activity滑动退出效果

    更新说明: 1.在QQ网友北京-旭的提醒下,在SlideFrame的initilize方法中添加了focusable.focusableInTouch.clickable的状态设置,否则会导致部分情况 ...

  6. 刀哥多线程笔记之gcd-02-block

    block 概念 block 是 C 语言的 是一种数据类型,可以当作参数传递 是一组预先准备好的代码,在需要的时候执行 动画 block 回顾 self.demoView.center = CGPo ...

  7. SQL基础篇---函数及其函数配套使用的关键字

    一.数值函数 知识点1 SUM 求总和 SELECT breakfast,sum(price) FROM my_foods GROUP BY breakfast ORDER BY SUM(price) ...

  8. 禁止生成文件Thumbs.db

    Thumbs.db是一个用于Microsoft Windows XP.Windows7 或 mac os x缓存Windows Explorer的缩略图的文件.Thumbs.db保存在每一个包含图片或 ...

  9. Linux下使用Magent+Memcached缓存服务器集群部署

    1.编译安装libevent  cd /root/soft_hhf/  wget http://cloud.github.com/downloads/libevent/libevent/libeven ...

  10. iOS进阶学习-CoreData

    一.CoreData数据库框架的优势 1.CoreData数据持久化框架是Cocoa API的一部分,首次在iOS5版本的系统中出现,它允许按照实体-属性-值模型组织数据,并以XML.二进制文件或者S ...