Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
174 views
in Technique[技术] by (71.8m points)

c++ - Override Ctrl-C

I am supposed override the CtrlC signal and use it to print a message. It is not supposed to end the program.

What happens so far is that when CtrlC is pressed it prints the message, but ends the program.

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:
" << 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)

}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Whoa, way too much code to sift through. However, if you use the C standard library, you should get the desired behaviour. Here's a C++ version:

#include <iostream>
#include <csignal>

sig_atomic_t sigflag = 0;

void sighandler(int s)
{
  // std::cerr << "Caught signal " << s << ".
"; // 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!
"; 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.

Note that signal handlers are inherited by fork()ed children.

The Posix function sigaction() allows you to register "one-shot" handlers which are replaced by the standard handler after they're invoked once. That's more advanced and Posix-specific, though.

Edit: As @Dietrich points out, you should never do any real work inside a signal handler. 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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...