简体   繁体   English

覆盖Ctrl-C

[英]Override Ctrl-C

I am supposed override the Ctrl C signal and use it to print a message. 我应该覆盖Ctrl C信号并用它来打印消息。 It is not supposed to end the program. 它不应该结束该计划。

What happens so far is that when Ctrl C is pressed it prints the message, but ends the program. 到目前为止发生的事情是当按下Ctrl C时它会打印消息,但会结束程序。

When I asked my professor he told me to do this: You need to make your signal handler keep from continuing to process the signal. 当我问我的教授他告诉我这样做时:你需要让信号处理程序不要继续处理信号。 Right now the signal is being handled by your code and then going on to the parent handler. 现在,信号由您的代码处理,然后转到父处理程序。

Is there a method I am supposed to add or do i need to move the signal installers someplace? 有没有我应该添加的方法,或者我需要在某个地方移动信号安装程序?

This is my code so far: 到目前为止这是我的代码:

#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)

}

Whoa, way too much code to sift through. 哇, 太多的代码去筛选。 However, if you use the C standard library, you should get the desired behaviour. 但是,如果使用C标准库,则应获得所需的行为。 Here's a C++ version: 这是一个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; }
  }
}

This will catch Ctrl-C (which raises SIGINT ), and the signal handler is not replaced, so it'll fire every time, and nobody is terminating the program. 这将捕获Ctrl-C (它引发SIGINT ),并且信号处理程序不会被替换,因此每次都会触发,并且没有人终止该程序。

Note that signal handlers are inherited by fork() ed children. 请注意,信号处理程序由fork() ed子项继承。

The Posix function sigaction() allows you to register "one-shot" handlers which are replaced by the standard handler after they're invoked once. Posix函数sigaction()允许您注册“一次性”处理程序,这些处理程序在调用一次后由标准处理程序替换。 That's more advanced and Posix-specific, though. 不过,这是更高级和Posix特有的。

Edit: As @Dietrich points out, you should never do any real work inside a signal handler. 编辑:正如@Dietrich指出的那样,你绝不应该信号处理程序中做任何真正的工作。 Rather, you should set a flag (I provided an example), and check for that flag inside your loop (and print the message there). 相反,你应该设置一个标志(我提供了一个例子),并检查你的循环中的那个标志(并在那里打印消息)。 I'll amend the example for that, too. 我也会修改这个例子。

Have you considered that inside your while loop there may be an interruptable function failing with 'EINTR'. 您是否考虑过在while循环中可能存在可中断的功能,并且“EINTR”失败。 You could might be able to fix it by using : 您可以使用以下方法修复它:

sa.sa_flags = SA_RESTART;

Or, just checking errno for it and looping. 或者,只需检查errno并循环。 Are you sure the program isn't reaching the end of termination. 你确定程序没有到达终止结束。 Try putting a print statement at the end of main. 尝试在main的末尾添加print语句。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM