覆盖按Ctrl-C [英] Override Ctrl-C

查看:232
本文介绍了覆盖按Ctrl-C的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我应该重写<大骨节病>控制 <大骨节病> C 信号,并用它来打印一条消息。这是不应该结束程序。

会发生什么事,到目前为止是,当<大骨节病>控制 <大骨节病> C 是pressed它打印消息,但结束程序。

当我问我的教授,他告诉我这样做:
你需要让你的信号处理程序持续处理信号保持。眼下信号是由您的code处理,然后继续到父处理程序。

有没有我应该增加或者我需要移动信号安装某个地方的方法?

这是我的code迄今:

 的#include&LT;&stdio.h中GT;
#包括LT&;&unistd.h中GT;
#包括LT&; SYS / wait.h&GT;
#包括LT&; SYS / types.h中&GT;
#包括LT&;&signal.h中GT;
#包括Input.h
#包括CircleBuff.h//无效handler_function(INT signal_id);无效catch_int(INT sig_num){    //再次复位信号处理程序catch_int,下一次
    信号(SIGINT,catch_int);
    //打印消息
    的printf(打印史);
    fflush(标准输出);
}无效printHistory(CircleBuff HIST){
    COUT&LT;&LT; 完整的历史:\\ n&LT;&LT; ENDL;
    hist.print();
    COUT&LT;&LT; ENDL;
}INT主(INT ARGC,字符** argv的){  结构的sigaction signal_action; / *定义表* /
  signal_action.sa_handler = catch_int; / *插入处理函数* /
  signal_action.sa_flags = 0; / *初始化标志字段* /
  sigemptyset(安培; signal_action.sa_mask); / *没有屏蔽的中断* /
  的sigaction(SIGINT,和放大器; signal_action,NULL); / *安装signal_action * /  做{
  //我的code:其中值报告内进行分配。  }而(报告!= 1)}


解决方案

哇,的办法的太多code去筛选。但是,如果您使用C标准库,你应该得到所需的行为。下面是一个C ++版本:

 的#include&LT;&iostream的GT;
#包括LT&;&csignal GT;sig_atomic_t sigflag = 0;无效sighandler(int类型)
{
  //的std :: CERR&LT;&LT; 中招信号&LT;&LT;小号所述&;&下; \\ n; //这是不确定的行为
  sigflag = 1; //类似的东西
}诠释的main()
{
  的std ::信号(SIGINT,sighandler);  // ...在这里你的程序...  //例如:宝宝的第一个循环(按Ctrl-D结束)
  焦炭℃;
  而(给std :: cin&GT;&GT; C)
  {
    如果(sigflag!= 0){性病:: CERR&LT;&LT; !信号\\ n; sigflag = 0; }
  }
}

这会赶上按Ctrl-C (这引起了 SIGINT ),信号处理程序不会被替换,因此它会火每一次,没有人被终止程序。

需要注意的是信号处理由继承叉() ED的孩子。

POSIX的功能的sigaction()允许您注册这是由标准处理器取代他们调用一次后,一次性的处理程序。这是更先进和POSIX特有的,虽然。

编辑:的作为@Dietrich所指出的,你应该永远不会做任何实际工作的的信号处理程序。相反,你应该设置一个标志(我提供了一个例子),并检查您的循环内的标志(和打印信息那里)。我将修改为例子了。

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:\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. Here's a C++ version:

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

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.

这篇关于覆盖按Ctrl-C的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆