1

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?

Zig Razor
  • 3,381
  • 2
  • 15
  • 35
bartop
  • 9,971
  • 1
  • 23
  • 54

1 Answers1

1

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.

Zig Razor
  • 3,381
  • 2
  • 15
  • 35