Как вызвать sigaction из C++

Я знаю, как использовать его в C (с signal.h), но библиотека <csignal> предоставляется в C++, и я хочу знать, включает ли она sigaction? Я попытался запустить его, но он сказал, что не найден. Мне было интересно, если я сделал что-то не так?

#include <iostream>
#include <string>
#include <cstdio>
#include <csignal>

namespace {
  volatile bool quitok = false;
  void handle_break(int a) {
    if (a == SIGINT) quitok = true;
  }
  std::sigaction sigbreak;
  sigbreak.sa_handler = &handle_break;
  sigbreak.sa_mask = 0;
  sigbreak.sa_flags = 0;
  if (std::sigaction(SIGINT, &sigbreak, NULL) != 0) std::perror("sigaction");
}

int main () {
  std::string line = "";
  while (!::quitok) {
    std::getline(std::cin, line);
    std::cout << line << std::endl;
  }
}

Но почему-то не работает. РЕДАКТИРОВАТЬ: Под «не работает» я подразумеваю, что компилятор дает сбой и говорит, что нет функции или структуры std::sigaction.

sigaction - это C POSIX, не так ли?


person Aiden Woodruff    schedule 19.08.2018    source источник
comment
sigaction не является частью стандартного C++, поэтому, можете ли вы его использовать, зависит от вашей реализации.   -  person    schedule 19.08.2018
comment
Несвязанный: volatile bool может быть недостаточно хорошим. Подробнее об этом: установить флаг в обработчике сигнала   -  person user4581301    schedule 19.08.2018
comment
Опишите Но почему-то не работает. более подробно. Не компилируется? Сигнал не обрабатывается? Программа вылетает? ...   -  person eerorika    schedule 19.08.2018
comment
но он сказал, что не найдено Что не было найдено? Что это сказало?   -  person eerorika    schedule 19.08.2018


Ответы (1)


sigaction находится в стандарте POSIX, а не в стандарте C++, и находится в глобальном пространстве имен. Вам также понадобится ключевое слово struct, чтобы различать sigaction, структуру, и sigaction, функцию. Наконец, код инициализации должен быть в функции — вы не можете иметь его в области файла.

#include <cstdio>
#include <signal.h>

namespace {
  volatile sig_atomic_t quitok = false;
  void handle_break(int a) {
    if (a == SIGINT) quitok = true;
  }
}

int main () {
  struct sigaction sigbreak;
  sigbreak.sa_handler = &handle_break;
  sigemptyset(&sigbreak.sa_mask);
  sigbreak.sa_flags = 0;
  if (sigaction(SIGINT, &sigbreak, NULL) != 0) std::perror("sigaction");
  //...
}
person PSkocik    schedule 19.08.2018
comment
Должен ли я использовать реализацию в <signal.h> или в пространстве имен в <csignal>? - person Aiden Woodruff; 19.08.2018
comment
@AidenWoodruff signal.h гарантированно будет иметь его на платформе POSIX. Я не думаю, что это верно для <csignal>. - person PSkocik; 19.08.2018
comment
почему quitok объявлен в безымянном пространстве имен? - person Saeid Yazdani; 07.02.2021
comment
@SaeidYazdani AFAIK, это должно иметь тот же эффект, что и объявление каждого из таких заключенных объявлений как static. - person PSkocik; 07.02.2021