重写Ctrl-C

我应该重写Ctrl C信号并使用它来打印一条消息。 它不应该结束程序。

到目前为止发生的事情是,当按下Ctrl C时,它会打印消息,但结束程序。

当我问我的教授时,他告诉我要这么做:你需要让信号处理器不要继续处理信号。 现在信号正在被您的代码处理,然后继续处理父处理程序。

有没有我应该添加的方法,或者我需要将信号安装程序移到某个位置?

这是我的代码到目前为止:

#include <stdio.h> #include <unistd.h> #include <sys/wait.h> #include <sys/types.h> #include <signal.h> #include "Input.h" #include "CircleBuff.h" //void handler_function(int signal_id); void catch_int(int sig_num){ //reset the signal handler again to catch_int, for next time signal(SIGINT, catch_int); //print message printf("Print History"); fflush(stdout); } void printHistory(CircleBuff hist){ cout << "Complete History:\n" << endl; hist.print(); cout << endl; } int main(int argc, char** argv){ struct sigaction signal_action; /* define table */ signal_action.sa_handler = catch_int; /* insert handler function */ signal_action.sa_flags = 0; /* init the flags field */ sigemptyset( &signal_action.sa_mask ); /* are no masked interrupts */ sigaction( SIGINT, &signal_action, NULL ); /* install the signal_action */ do{ //My code: where the value report will be assigned within. } while(report != 1) } 

Solutions Collecting From Web of "重写Ctrl-C"

哇,太多的代码筛选通过。 但是,如果使用C标准库,则应该获得所需的行为。 这是一个C ++版本:

 #include <iostream> #include <csignal> sig_atomic_t sigflag = 0; void sighandler(int s) { // std::cerr << "Caught signal " << s << ".\n"; // this is undefined behaviour sigflag = 1; // something like that } int main() { std::signal(SIGINT, sighandler); // ... your program here ... // example: baby's first loop (Ctrl-D to end) char c; while (std::cin >> c) { if (sigflag != 0) { std::cerr << "Signal!\n"; sigflag = 0; } } } 

这将捕获Ctrl-C (这会引发SIGINT ),并且信号处理程序不会被替换,所以每次都会触发,没有人正在终止程序。

请注意,信号处理程序由fork()子代继承。

Posix函数sigaction()允许您在被调用一次之后注册由标准处理程序替换的“一次性”处理程序。 虽然这是更先进的和Posix的具体。

编辑:正如@Dietrich指出,你不应该信号处理程序中做任何真正的工作。 相反,你应该设置一个标志(我提供了一个例子),并检查你的循环内的标志(并在那里打印消息)。 我也会修改这个例子。

你有没有考虑到在你的while循环中可能会有一个可中断的函数与'EINTR'失败。 你可能可以通过使用以下方法来修复它:

 sa.sa_flags = SA_RESTART; 

或者,只需检查errno并循环。 你确定这个程序没有到达终止的地步吗? 尝试在主要结尾处放置打印语句。