【问题标题】:How can i use sigaction() to intercept SIGINT?如何使用 sigaction() 拦截 SIGINT?
【发布时间】:2017-01-27 00:55:09
【问题描述】:

我正在尝试修改以下代码以使用 sigaction() 拦截 SIGINT;

我需要将“for”循环替换为“while(1);你应该可以通过输入“^\”退出程序。(需要拦截SIGQUIT。)

#include <signal.h>
#include <unistd.h>
#include <iostream>

using namespace std;

void func ( int sig )
{
     cout << "Oops! -- I got a signal " << sig << endl;
}

int main()
{
    (void) signal ( SIGINT, func ); //catch terminal interrupts

    //for ( int i = 0; i < 20; ++i )
    while(1) 
    {
         cout << "signals" << endl;
         sleep ( 1 ); 
    }
    return 0;
}

【问题讨论】:

  • SIGINT 还是 SIGQUIT?是哪一个?
  • 您需要使用正确的信息设置struct sigaction 变量。然后您调用sigaction() 而不是signal()。其余大部分保持不变。请注意,在信号处理程序中调用 cout &lt;&lt; … 很可能是“未定义的行为”。见How to avoid using printf() in a signal handler。它只适用于 C,但类似的概念也适用于 C++。

标签: c++ operating-system signals


【解决方案1】:

您可以使用sigaction 捕获SIGINT(并且仍然具有您描述的输出),并使用以下代码(在类似 Unix 的操作系统上使用 clang 编译并为我工作):

#include <signal.h>
#include <iostream>
#include <unistd.h>

static int sigcaught = 0;

static void sighandler(int signum)
{
    sigcaught = signum;
}

int main()
{
    int signum = SIGINT;

    struct sigaction newact;
    struct sigaction oldact;
    newact.sa_handler = sighandler;
    sigemptyset(&newact.sa_mask);
    newact.sa_flags = 0;

    sigaction(signum, &newact, &oldact);

    while (!sigcaught)
    {
        std::cout << "waiting for signal" << std::endl;
        sleep(1);
    }
    std::cout << "Oops! -- I got a signal " << sigcaught << std::endl;
    return 0;
}

请注意:此代码故意不检查返回值(例如来自sigactionsleep),因为原始代码不是,因为检查它们可能会分散读者看到相关差异。但是,我不希望生产代码忽略返回值(尤其是那些可以指示错误的值)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-15
    • 2011-09-26
    • 1970-01-01
    • 2018-07-08
    • 2013-03-08
    相关资源
    最近更新 更多