以下代码仅捕获“SIGINT”信号一次然后中断(程序存在):
#include <signal.h>
#include <stdio.h>
void IntHandler(int value);
void CatchIntSignal()
{
struct sigaction intAction;
intAction.sa_handler = IntHandler;
sigemptyset(&intAction.sa_mask);
intAction.sa_flags = 0;
//if to uncomment any of "0" or "SIG_IGN" - IntHandler will be never called:
//intAction.sa_sigaction = 0/*SIG_IGN*/;
if(sigaction(SIGINT, &intAction, NULL) != 0)
{
printf("sigaction() failed.\n");
}
}
void IntHandler(int value)
{
printf("IntHandler(%d)\n", value);
//uncommenting this does not help:
//CatchIntSignal();
}
int main()
{
CatchIntSignal();
getchar();
return 0;
}
如何修改此代码以在SIGINT捕获后保留程序的退出? 如果将 intAction.sa_sigaction 设置为0或SIG_IGN - 永远不会调用IntHandler - 但为什么呢?哪个未定义的值必须说系统“必须调用IntHandler”?如果我将一些处理程序设置为 intAction.sa_sigaction - 将调用此处理程序(但IntHandler不会)。系统如何知道我确实设置了 intAction.sa_sigaction ?
答案 0 :(得分:4)
您的问题是sa_handler
的{{1}}和sa_sigaction
字段实际上是相同的字段。引用struct sigaction
:( / p>)的(OSX)联机帮助页
sigaction(2)
因此,您对 struct sigaction {
union __sigaction_u __sigaction_u; /* signal handler */
sigset_t sa_mask; /* signal mask to apply */
int sa_flags; /* see signal options below */
};
union __sigaction_u {
void (*__sa_handler)(int);
void (*__sa_sigaction)(int, struct __siginfo *,
void *);
};
#define sa_handler __sigaction_u.__sa_handler
#define sa_sigaction __sigaction_u.__sa_sigaction
的分配将覆盖您已设置的处理程序。您应该设置sa_sigaction
并单独留下sa_handler
。这就是sa_sigaction
应该阅读的内容:
CatchIntSignal
(您可能需要添加void CatchIntSignal()
{
struct sigaction intAction;
intAction.sa_handler = IntHandler;
sigemptyset(&intAction.sa_mask);
intAction.sa_flags = SA_RESTART;
if(sigaction(SIGINT, &intAction, NULL) != 0)
printf("sigaction() failed: %s\n", strerror(errno));
}
和string.h
的#includes以获取errno.h
位进行编译。在系统调用失败时触发的错误消息中始终包含strerror(errno)
。)
(更正:将strerror(errno)
添加到每个ninjalj的标记。)
答案 1 :(得分:2)
您的麻烦可能是系统调用被中断,因此getchar()
返回,可能是EOF。该计划的下一步是退出...
因此,您可以尝试检查getchar()
返回的内容,重置stdin
上的错误状态,然后再次致电getchar()
以获取下一个信号。
答案 2 :(得分:0)
捕获中断信号并在捕获代码中处理后,需要将处理设置回SIG_DFL
。