signal

  • Post author:
  • Post category:其他


sigaction(查询或设置信号处理方式)

相关函数

signal,sigprocmask,sigpending,sigsuspend

表头文件

#include

定义函数

int sigaction(int signum,const struct sigaction *act ,struct sigaction *oldact);

函数说明

sigaction()会依参数signum指定的信号编号来设置该信号的处理函数。参数signum可以指定SIGKILL和SIGSTOP以外的所有信号。

如参数结构sigaction定义如下

struct sigaction

{

void (*sa_handler) (int);

sigset_t sa_mask;

int sa_flags;

void (*sa_restorer) (void);

}

sa_handler此参数和signal()的参数handler相同,代表新的信号处理函数,其他意义请参考signal()。

sa_mask 用来设置在处理该信号时暂时将sa_mask 指定的信号搁置。

sa_restorer 此参数没有使用。

sa_flags 用来设置信号处理的其他相关操作,下列的数值可用。

OR 运算(|)组合

A_NOCLDSTOP : 如果参数signum为SIGCHLD,则当子进程暂停时并不会通知父进程

SA_ONESHOT/SA_RESETHAND:当调用新的信号处理函数前,将此信号处理方式改为系统预设的方式。

SA_RESTART:被信号中断的系统调用会自行重启

SA_NOMASK/SA_NODEFER:在处理此信号未结束前不理会此信号的再次到来。

如果参数oldact不是NULL指针,则原来的信号处理方式会由此结构sigaction 返回。

返回值

执行成功则返回0,如果有错误则返回-1。

错误代码

EINVAL 参数signum 不合法, 或是企图拦截SIGKILL/SIGSTOPSIGKILL信号

EFAULT 参数act,oldact指针地址无法存取。

EINTR 此调用被中断

范例

#include

#include

void show_handler(struct sigaction * act)

{

switch (act->sa_flags)

{

case SIG_DFL:printf(“Default actionn”);break;

case SIG_IGN:printf(“Ignore the signaln”);break;

default: printf(“0x%xn”,act->sa_handler);

}

}

main()

{

int i;

struct sigaction act,oldact;

act.sa_handler = show_handler;

act.sa_flags = SA_ONESHOT|SA_NOMASK;

sigaction(SIGUSR1,&act,&oldact);

for(i=5;i<15;i++)

{

printf(“sa_handler of signal %2d =”.i);

sigaction(i,NULL,&oldact);

}

}

执行

sa_handler of signal 5 = Default action

sa_handler of signal 6= Default action

sa_handler of signal 7 = Default action

sa_handler of signal 8 = Default action

sa_handler of signal 9 = Default action

sa_handler of signal 10 = 0x8048400

sa_handler of signal 11 = Default action

sa_handler of signal 12 = Default action

sa_handler of signal 13 = Default action

sa_handler of signal 14 = Default action

sigaddset(增加一个信号至信号集)

相关函数

sigemptyset,sigfillset,sigdelset,sigismember

表头文件

#include

定义函数

int sigaddset(sigset_t *set,int signum);

函数说明

sigaddset()用来将参数signum 代表的信号加入至参数set 信号集里。

返回值

执行成功则返回0,如果有错误则返回-1。

错误代码

EFAULT 参数set指针地址无法存取

EINVAL 参数signum非合法的信号编号

sigdelset(从信号集里删除一个信号)

相关函数

sigemptyset,sigfillset,sigaddset,sigismember

表头文件

#include

定义函数

int sigdelset(sigset_t * set,int signum);

函数说明

sigdelset()用来将参数signum代表的信号从参数set信号集里删除。

返回值

执行成功则返回0,如果有错误则返回-1。

错误代码

EFAULT 参数set指针地址无法存取

EINVAL 参数signum非合法的信号编号

sigemptyset(初始化信号集)

相关函数

sigaddset,sigfillset,sigdelset,sigismember

表头文件

#include

定义函数

int sigemptyset(sigset_t *set);

函数说明

sigemptyset()用来将参数set信号集初始化并清空。

返回值

执行成功则返回0,如果有错误则返回-1。

错误代码

EFAULT 参数set指针地址无法存取

sigfillset(将所有信号加入至信号集)

相关函数

sigempty,sigaddset,sigdelset,sigismember

表头文件

#include

定义函数

int sigfillset(sigset_t * set);

函数说明

sigfillset()用来将参数set信号集初始化,然后把所有的信号加入到此信号集里。

返回值

执行成功则返回0,如果有错误则返回-1。

附加说明

EFAULT 参数set指针地址无法存取

sigismember(测试某个信号是否已加入至信号集里)

相关函数

sigemptyset,sigfillset,sigaddset,sigdelset

表头文件

#include

定义函数

int sigismember(const sigset_t *set,int signum);

函数说明

sigismember()用来测试参数signum 代表的信号是否已加入至参数set信号集里。如果信号集里已有该信号则返回1,否则返回0。

返回值

信号集已有该信号则返回1,没有则返回0。如果有错误则返回-1。

错误代码

EFAULT 参数set指针地址无法存取

EINVAL 参数signum 非合法的信号编号

signal(设置信号处理方式)

相关函数

sigaction,kill,raise

表头文件

#include

定义函数

void (*signal(int signum,void(* handler)(int)))(int);

函数说明

signal()会依参数signum 指定的信号编号来设置该信号的处理函数。当指定的信号到达时就会跳转到参数handler指定的函数执行。如果参数handler不是函数指针,则必须是下列两个常数之一:

SIG_IGN 忽略参数signum指定的信号。

SIG_DFL 将参数signum 指定的信号重设为核心预设的信号处理方式。

关于信号的编号和说明,请参考附录D

返回值

返回先前的信号处理函数指针,如果有错误则返回SIG_ERR(-1)。

附加说明

在信号发生跳转到自定的handler处理函数执行后,系统会自动将此处理函数换回原来系统预设的处理方式,如果要改变此操作请改用sigaction()。

范例

参考alarm()或raise()。

sigpending(查询被搁置的信号)

相关函数

signal,sigaction,sigprocmask,sigsuspend

表头文件

#include

定义函数

int sigpending(sigset_t *set);

函数说明

sigpending()会将被搁置的信号集合由参数set指针返回。

返回值执

行成功则返回0,如果有错误则返回-1。

错误代码

EFAULT 参数set指针地址无法存取

EINTR 此调用被中断。

sigprocmask(查询或设置信号遮罩)

相关函数

signal,sigaction,sigpending,sigsuspend

表头文件

#include

定义函数

int sigprocmask(int how,const sigset_t *set,sigset_t * oldset);

函数说明

sigprocmask()可以用来改变目前的信号遮罩,其操作依参数how来决定

SIG_BLOCK 新的信号遮罩由目前的信号遮罩和参数set 指定的信号遮罩作联集

SIG_UNBLOCK 将目前的信号遮罩删除掉参数set指定的信号遮罩

SIG_SETMASK 将目前的信号遮罩设成参数set指定的信号遮罩。

如果参数oldset不是NULL指针,那么目前的信号遮罩会由此指针返回。

返回值

执行成功则返回0,如果有错误则返回-1。

错误代码

EFAULT 参数set,oldset指针地址无法存取。

EINTR 此调用被中断

。。。。。。。。。。。。。。。例程。。。。。。。。。。。。。。。。。。。。

======================================

#include <stdio.h>

#include <unistd.h>

#include <signal.h>

#include <stdlib.h>


static void sig_quit(int signo)

{


printf(“caught SIGQUIT/n”);

signal(SIGQUIT, SIG_DFL);

}

int main()

{


sigset_t newmask;

sigset_t oldmask;

sigset_t pendmask;

signal(SIGQUIT, sig_quit);

sigemptyset(&newmask);

sigaddset(&newmask, SIGQUIT);

sigprocmask(SIG_BLOCK, &newmask, &oldmask);

sleep (5);

sigpending(&pendmask);

//        sleep (5);

if (sigismember(&pendmask, SIGQUIT))

{


printf(“/nSIGQUIT pending/n”);

}

sigprocmask(SIG_SETMASK, &oldmask, NULL);

printf(“SIGQUIT unblocked/n”);

sleep(5);

return (0);

}

============================================

#include <time.h>

#include <stdio.h>

#include <signal.h>

#include <sys/types.h>

#include <errno.h>

#include <stdlib.h>

#include <unistd.h>

int main(int argc, char *argv[])

{

sigset_t allSignal;

sigfillset(&allSignal);

if (-1 == sigprocmask(SIG_SETMASK, &allSignal, NULL))

{


exit(-1);

}

alarm(2);


sigset_t waitSignals;

sigemptyset(&waitSignals);

sigaddset(&waitSignals, SIGTERM);

sigaddset(&waitSignals, SIGALRM);

sigaddset(&waitSignals, SIGHUP);


int pid = fork();

if(pid<0)

{


printf(“fork error!/n”);

exit(1);

}

else if (pid == 0)

{


printf(“child pid:%d/n”,getpid());

printf(“child parent pid:%d/n”,getppid());

for(int i = 0; i < 10; i++)

{


sleep(1);

if((kill(getppid(),SIGHUP))==-1)

{


perror(“kill”);

exit(1);

}

}

kill(getppid(),SIGTERM);

exit(EXIT_SUCCESS);

}

if(pid>0)

{

printf(“parent pid:%d/n”,getpid());

while (1)

{


int sign = 0;

if (sigwait(&waitSignals, &sign) != 0)

{


continue;

}

if (SIGTERM == sign)

{


printf(“signal SIGTERM/n”);

exit(0);

}

if (SIGHUP == sign)

{


printf(“signal SIGHUP/n”);

}

if (SIGALRM == sign)

{


printf(“signal SIGALRM/n”);

alarm(2);

}

}

}

}