#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
/*
* 是标准C库中用于操作自定义信号集的一个函数
*/
#if 0
用于检查一个指定的信号是否在给定的信号集中,也就是检查该信号是否被阻塞
int sigismember(const sigset_t *set, int signum);
set:指向sigset_t类型的指针,sigset_t是一个信号集类型,表示一个信号集。
signum:要检查的信号编号。
如果指定的信号在信号集中,sigismember()函数返回1;如果指定的信号不在信号集中,返回0。
失败时,返回-1,并设置errno表示错误原因。
允许您将一个指定的信号添加到一个自定义信号集中,也就是将该信号的标准位设为1,表示阻塞这个信号
int sigaddset(sigset_t *set, int signum);
set:指向sigset_t类型的指针,sigset_t是一个信号集类型,表示一个信号集。
signum:需要添加到信号集中的信号编号。
成功时,sigaddset()函数返回0;
失败时,返回-1,并设置errno表示错误原因。
允许从一个自定义信号集中删除一个指定的信号,也就是将该信号的标准位设为0,不阻塞这个信号。
int sigdelset(sigset_t *set, int signum);
set:指向sigset_t类型的指针,sigset_t是一个信号集类型,表示一个信号集。
signum:需要从信号集中删除的信号编号。
成功时,sigdelset()函数返回0;
失败时,返回-1,并设置errno表示错误原因。
初始化一个自定义信号集,将其所有信号都清空,也就是将信号集中的所有的标志位置为0,
使得这个集合不包含任何信号,也就是不阻塞任何信号。
int sigemptyset(sigset_t *set);
set:指向sigset_t类型的指针,sigset_t是一个信号集类型,用于表示一个信号集。
把用这个指针指向的信号集清空,也就是不阻塞任何信号。
成功时,返回0;
失败时,返回-1,并设置errno表示错误原因。
#endif
/*
* 使用sigaddset()函数创建一个包含SIGINT和SIGTERM信号的信号集
*/
int add_signal_set()
{
sigset_t signal_set;
// 使用sigemptyset()初始化信号集,清空所有信号
if (sigemptyset(&signal_set) == -1) {
perror("sigemptyset");
return 1;
}
// 使用sigaddset()将SIGINT信号添加到信号集中
if (sigaddset(&signal_set, SIGINT) == -1) {
perror("sigaddset");
return 1;
}
// 使用sigaddset()将SIGTERM信号添加到信号集中
if (sigaddset(&signal_set, SIGTERM) == -1) {
perror("sigaddset");
return 1;
}
// 检查信号集中是否包含SIGINT和SIGTERM信号
int result1 = sigismember(&signal_set, SIGINT);
int result2 = sigismember(&signal_set, SIGTERM);
if (result1 == -1 || result2 == -1) {
perror("sigismember");
return 1;
} else if (result1 == 1 && result2 == 1) {
printf("SIGINT and SIGTERM are in the signal set.\n");
}
return 0;
}
/*
* 使用sigdelset()函数从信号集中删除SIGINT信号
*/
int del_signal_set()
{
sigset_t signal_set;
// 使用sigfillset()初始化信号集,包含所有可接受的信号
if (sigfillset(&signal_set) == -1) {
perror("sigfillset");
return 1;
}
// 使用sigdelset()从信号集中删除SIGINT信号
if (sigdelset(&signal_set, SIGINT) == -1) {
perror("sigdelset");
return 1;
}
// 检查信号集中是否包含SIGINT信号
int result = sigismember(&signal_set, SIGINT);
if (result == -1) {
perror("sigismember");
return 1;
} else if (result == 0) {
printf("SIGINT is not in the signal set.\n");
} else {
printf("SIGINT is in the signal set.\n");
}
return 0;
}
void show_handler(int sig)
{
printf("I got signal %d\n", sig);
int i;
for(i = 0; i < 5; i++)
{
printf("i = %d\n", i);
sleep(1);
}
}
int main(void)
{
int i = 0;
struct sigaction act, oldact;
act.sa_handler = show_handler;
sigaddset(&act.sa_mask, SIGQUIT);
act.sa_flags = SA_RESETHAND | SA_NODEFER; // note 1
//act.sa_flags = 0;
sigaction(SIGINT, &act, &oldact);
while(1) {
sleep(1);
printf("sleeping %d\n", i);
i++;
}
}
#if 0
1.如果在信号SIGINT(Ctrl + c)的信号处理函数show_handler执行过程中,本进程收到信号SIGQUIT(Crt+\),
将阻塞该信号,直到show_handler执行结束才会处理信号SIGQUIT。
#endif