问题描述
|
以下代码仅捕获\“ 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进行了设置?
解决方法
您的问题是
struct sigaction
的sa_handler
和sa_sigaction
字段实际上是同一字段。在(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
。这是ѭ9的读法:
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));
}
(您可能需要添加include11ѭ和errno.h
的#includes才能编译strerror(errno)
位。在系统调用失败时触发的错误消息中始终包含strerror(errno)
。)
(更正:每个忍者的旗帜上加SA_RESTART
。)
,您的麻烦可能是系统调用被中断,因此the16ѭ返回,可能带有EOF。程序接下来要做的是退出...
因此,您可以尝试检查getchar()
返回什么,在stdin
上重置错误状态,然后再次调用getchar()
以获取下一个信号。
,捕获到中断信号并在捕获代码中进行处理后,需要将处理设置回SIG_DFL
。
编辑:请忽略。这仅适用于旧的unix signal()。