Dims
Dims

Reputation: 51249

How to check stdin is empty with no hang?

I would like my program to read data from either command line option or stdin (redirected). How to check that stdin is empty or not then?

Doing fgetc hangs my program if stdin is empty (waiting for input). Calling feof returns false.

Also tried

ioctl(0, I_NREAD, &n) == 0 && n > 0

but I don't have I_NREAD defined (on Raspi, but I want portable).

How to accomplish?

Upvotes: 1

Views: 287

Answers (1)

Zan Lynx
Zan Lynx

Reputation: 54393

The select function can do it on a POSIX system. On Windows or others you would need other options.

Note that if the shell sets up the pipeline and the operating system schedules the child to run first (first | child) it could execute the select and not find any input ready to read.

Note that I changed the timeout from 0 to 100,000 microseconds (0.1 seconds) which helps avoid randomly missing the input. However, if the system is under heavy load it could still fail to detect stdin being ready to read.

See:

#include <stdio.h>
#include <sys/select.h>

int main() {
  fd_set read_fds;
  struct timeval tv = {0, 100000};
  int fd = fileno(stdin);
  int r;

  FD_ZERO(&read_fds);
  FD_SET(fd, &read_fds);
  r = select(fd + 1, &read_fds, NULL, NULL, &tv);
  if (r > 0) {
    char buffer[256];
    if (fgets(buffer, 256, stdin)) {
      puts(buffer);
    }
  }
  return 0;
}

Upvotes: 1

Related Questions