Подтвердить что ты не робот

Перекрыть 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)

}
4b9b3361

Ответ 1

Эй, слишком много кода для просеивания. Однако, если вы используете стандартную библиотеку 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 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() ed.

Функция Posix sigaction() позволяет вам регистрировать обработчики "один выстрел", которые заменяются стандартным обработчиком после их однократного вызова. Это более продвинутый и Posix-специфический, хотя.

Изменить: Как указывает @Dietrich, вы никогда не должны делать никакой реальной работы внутри обработчика сигнала. Скорее, вы должны установить флаг (я привел пример) и проверить этот флаг внутри вашего цикла (и распечатать там сообщение). Я также исправлю пример для этого.

Ответ 2

Считаете ли вы, что внутри цикла while может быть прерывистая функция, которая не работает с "EINTR". Возможно, вы могли бы исправить это, используя:

sa.sa_flags = SA_RESTART;

Или просто проверяем errno на это и зацикливаем. Вы уверены, что программа не доходит до конца завершения. Попробуйте поставить оператор печати в конце основного.