bartop
bartop

Reputation: 10315

ifstream from named pipe - check nonblocking if there is data

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

Answers (1)

Zig Razor
Zig Razor

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

Related Questions