Reputation: 10315
To check 'regular' std::istream
if there is any pending data I can do just something like this:
bool has_pending_data(std::istream& s) {
return s.peek() >= 0;
}
However, this is different for standard input and named pipes. If I do something like this:
if (has_pending_data(std::cin)) {
// process incoming data
} else {
// do some periodic tasks
}
the else branch is never reached since the execution will block on the peek
function. Is there way to avoid this blocking for standerd input and named pipes?
Upvotes: 1
Views: 805
Reputation: 3535
The problem is that when std::cin
does not have character in the I/O buffer, the peek
does not return with EOF, but wait till at least a character is written.
This because the iostream library doesn't support the concept of non-blocking I/O. I don't think there's anything in the C++ standard that does.
This code can help you to check existence of data in the stdin without blocking:
std::cin.seekg(0, std::cin.end);
int length = std::cin.tellg();
if (length < 0) return; //- no chars available
If stdin has some data - don't forget to set the position back to the beginning.
std::cin.seekg(0, std::cin.beg);
In alternative you can try to use the select function. It's usually used for networking stuff, but it'll work just fine if you pass it the file descriptor for stdin.
Upvotes: 1