Reputation: 51249
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
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