有关捕获Unix信号的问题

问题描述

| 以下代码仅捕获\“ 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()。