《unix环境高级编程》信号——sigaction 函数
2014-11-25 16:27
309 查看
sigaction 函数
sigaction 函数的功能与 signal 类似,用于检查或修改与指定信号相关联的处理动作,一般在应用中使用 sigaction 函数。[cpp] view
plaincopy
/* sigaction函数 */
/*
* 函数功能: 检查或修改与指定信号相关联的处理动作;此函数取代之前的signal函数;
* 返回值:若成功则返回0,若出错则返回-1;
* 函数原型:
*/
#include <signal.h>
int sigaction(int signo, const struct sigaction *act, struct sigaction *oact);
/*
* 说明:
* signo是要检查或修改其具体动作的信号编号;
* 若act非空,则要修改其动作;
* 若oact指针非空,则系统经由oact指针返回该信号上一个动作;
*
* struct sigaction 结构如下:
*/
struct sigaction
{
void (* sa_handler)(int); /* addr of signal handler, or SIG_IGN, or SIG_DFL */
sigset_t sa_mask; /* additional signals to block */
int sa_flags; /* signal options */
/* alternate handler */
void (*sa_sigaction)(int, siginfo_t *, void *);
};
/*
* 说明:
* 当更改动作时,若sa_handler 字段包含一个信号捕捉函数的地址,则sa_mask字段说明了一个信号集,在调用该信号捕捉函数之前,
* 这一信号集要加到进程的信号屏蔽字中。仅当从信号捕获函数返回时再将进程的信号屏蔽字复位为原先值;
* 其中sa_flags标志如下:
* (1)SA_INTERRUPT 由此信号中断的系统调用不会自动重启;
* (2)SA_NOCLDSTOP 若signo是SIGCHLD,当子进程停止时,不产生此信号,当子进程终止时,仍然产生此信号;若已设置此标志,则当停止的进程继续运行时,不发送SIGCHLD信号;
* (3)SA_NOCLDWAIT 若signo是SIGCHLD,当子进程停止时,不创建僵死进程;若调用进程后面调用wait,则调用进程阻塞,直到其所有子进程都终止,此时返回-1,并将errno设置为ECHILD;
* (4)SA_NOEFER 当捕捉到此信号时,在执行其信号捕捉函数时,系统不自动阻塞此信号;
* (5)SA_NOSTACK 若用signaltstack(2)声明了一替换栈,则将此信号传递给替换栈上的进程;
* (6)SA_RESETHAND 在此信号捕捉函数入口处,将此信号的处理方式复位为SIG_DEL,并清除SA_SIGINFO标志;
* (7)SA_RESTART 由此信号中断的系统调用会自动重启动;
* (8)SA_SIGINFO 此选项对信号处理程序提供附加信息:一个指向siginfo结构的指针以及一个指向进程上下文标识符的指针;
*/
sa_sigaction 字段是一个替代的信号处理程序,当在 sigaction 结构中使用了 SA_SIGINFO 标志时,使用该信号处理程序。通常,按下列方式调用信号处理程序:
[cpp] view
plaincopy
void handler(int signo);
如果设置了 SA_SIGINFO 标志,那么按照下列方式调用信号处理程序:
[cpp] view
plaincopy
void handler(int signo, siginfo_t *info, void *context);
//siginfo 的结构如下:
struct siginfo{
int sig_signo; //信号编号
int sig_errno; //如果不是0,就是errno.h中的errno值
int sig_code; //附加信息(取决于信号)
pid_t si_pid; //发送信号的进程ID
uid_t sig_uid; //发送信号的进程实际用户ID
void *si_addr; //产生错误的地址
int si_status; //退出值或者信号值
long si_band; //SIGPOLL的band号
//可能还会有其他的值。
}
下面可以 sigaction 函数实现 signal 函数的功能:
[cpp] view
plaincopy
#include "apue.h"
Sigfunc *signal(int signo, Sigfunc *func)
{
struct sigaction act, oact;
/* 设置信号处理函数 */
act.sa_handler = func;
/* 初始化信号集 */
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
if(signo == SIGALRM)
{/* 若是SIGALRM信号,则系统不会自动重启 */
#ifdef SA_INTERRUPT
act.sa_flags |= SA_INTERRUPT;
#endif
}
else
{/* 其余信号设置为系统会自动重启 */
#ifdef SA_RESTART
act.sa_flags |= SA_RESTART;
#endif
}
/* 调用 sigaction 函数 */
if(sigaction(signo, &act, &oact) < 0)
return(SIG_ERR);
return(oact.sa_handler);
}
测试程序:
[cpp] view
plaincopy
#include <sys/types.h>
#include "apue.h"
#include <signal.h>
static Sigfunc *Msignal(int signo, Sigfunc *func);
static void sig_func(int signo);
int main(void)
{
if(Msignal(SIGALRM,sig_func) == SIG_ERR)
err_sys("SIGALRM error");
if(Msignal(SIGHUP,sig_func) == SIG_ERR)
err_sys("SIGHUP error");
printf("kill...\n");
kill(getpid(),SIGHUP);
printf("alarm...\n");
alarm(5);
pause();
printf("exit.\n");
exit(0);
}
static void sig_func(int signo)
{
if(SIGHUP == signo)
printf("Recevied kill.\n");
else if(SIGALRM == signo)
printf("Recevied alarm.\n");
else
printf("Recevied others.\n");
}
static Sigfunc *Msignal(int signo, Sigfunc *func)
{
struct sigaction act, oact;
/* 设置信号处理函数 */
act.sa_handler = func;
/* 初始化信号集 */
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
if(signo == SIGALRM)
{/* 若是SIGALRM信号,则系统不会自动重启 */
#ifdef SA_INTERRUPT
act.sa_flags |= SA_INTERRUPT;
#endif
}
else
{/* 其余信号设置为系统会自动重启 */
#ifdef SA_RESTART
act.sa_flags |= SA_RESTART;
#endif
}
/* 调用 sigaction 函数 */
if(sigaction(signo, &act, &oact) < 0)
return(SIG_ERR);
return(oact.sa_handler);
}
输出结果:
[cpp] view
plaincopy
kill...
Recevied kill.
alarm...
Recevied alarm.
exit.
相关文章推荐
- 《unix环境高级编程》信号——sigaction 函数
- linux信号机制之sigaction结构体浅析,signal 函数,信号捕捉
- Linux下信号处理函数sigaction
- linux信号之sigaction结构体 signal 函数
- 《unix环境高级编程》信号——sigsetjmp 函数和 siglongjmp 函数
- linux信号机制之sigaction结构体浅析,signal 函数,信号捕捉
- linux信号机制之sigaction结构体浅析,signal 函数,信号捕捉
- linux 信号的捕捉和发送函数的简单使用:sigaction()和sigqueue()
- Linux信号signal介绍,signal()函数,sigaction()函数
- linux信号机制之sigaction结构体浅析,signal 函数,信号捕捉
- linux信号机制之sigaction结构体浅析,signal 函数,信号捕捉
- linux系统编程之信号(六):信号发送函数sigqueue和信号安装函数sigaction
- linux系统编程之信号(六):信号发送函数sigqueue和信号安装函数sigaction
- linux系统编程之信号(六):信号发送函数sigqueue和信号安装函数sigaction
- struct sigaction 和信号处理函数的一些说明
- linux信号机制之sigaction 浅析,signal 函数,信号捕捉 信号编码意义
- linux信号机制之sigaction结构体浅析,signal 函数,信号捕捉
- 信号发送函数sigqueue和信号安装函数sigaction
- 2信号处理之:信号产生原因,进程处理信号行为,信号集处理函数,PCB的信号集,sigprocmask()和sigpending(),信号捕捉设定,sigaction,C标准库信号处理函数,可重入函数,
- 信号相关函数(signal,sigaction,sigprocmask, kill,sigqueue信号发送函数,睡眠函数,计时器函数)