Reputation: 13
I have the following code:
struct sigaction act = {{0}};
act.sa_handler = handler;
sigaction(SIGINT, &act, nullptr);
while (true)
{
std::cout << "input:";
std::getline(std::cin, line);
// Handle line
}
When I receive SIGINT, the program gets stuck in an infinite loop. I can't simply set SA_RESTART (like here) because I want to print a message when I receive the signal.
I don't want to print directly from the handler, so I set a flag in it and check it in the loop.
if (flag)
std::count << "got SIGINT" << std::endl;
SA_RESTART causes getline to block, so I can't reach this if and handle the signal unless getline returns. Is there anyway around this?
edit(full example):
#include <iostream>
#include <signal.h>
bool flag = false;
void handler(int signum)
{
flag = true;
}
int main()
{
struct sigaction act = {{0}};
act.sa_handler = handler;
//act.sa_flags = SA_RESTART;
sigaction(SIGINT, &act, nullptr);
while (true)
{
std::cout << "input:";
std::string line;
std::getline(std::cin, line);
if (flag) {
std::cout << "got SIGINT" << std::endl;
flag = false;
}
}
}
Upvotes: 1
Views: 1654
Reputation: 136365
bool flag = false;
is not correct when flag
is being set by a signal handler.
Correct:
std::sig_atomic_t volatile flag = false;
See std::sig_atomic_t
for more details.
Upvotes: 0
Reputation: 14046
When getline
is interrupted an error flag will be set on cin
. That needs to be cleared to prevent getline
from continuously failing.
if (flag) {
std::cout << "got SIGINT" << std::endl;
flag = false;
std::cin.clear();
}
Upvotes: 3