Select always returns 0 in an input file
I wrote a function function that receives FILE*
and checks if it is ready.
The function:
int ioManager_nextReady(FILE *IFILE) {
// Setting input ifle
int inDescrp = fileno(IFILE ? IFILE : stdin);
// Setting timer to 0
struct timeval timeout;
timeout.tv_sec = timeout.tv_usec = 0;
// Variables for select
unsigned short int nfds = 1;
fd_set readfds;
FD_ZERO(&readfds);
FD_SET(inDescrp, &readfds);
// Run select
int nReady = select(nfds, &readfds, NULL, NULL, &timeout);
if (nReady > 0) {
return inDescrp;
}
return -1;
}
I am trying to test this function with check.h
.
The tests:
static FILE *tmpIn;
void before(char *line) {
tmpIn = tmpfile();
if (line) {
fprintf(tmpIn, "%s\n", line);
rewind(tmpIn);
fflush(tmpIn);
}
}
void after() { fclose(tmpIn); }
START_TEST(test_ioManager_nextReady_NULL) {
before(NULL);
int data;
data = ioManager_nextReady(tmpIn);
ck_assert_int_eq(data, -1);
after();
}
END_TEST
#define LINEIN "Sample input"
START_TEST(test_ioManager_nextReady_text) {
before(LINEIN);
int data;
data = ioManager_nextReady(tmpIn);
ck_assert_int_ne(data, -1);
after();
}
END_TEST
The result:
Running suite(s): IOManager
50%: Checks: 2, Failures: 1, Errors: 0
ioManager.test.c:42:F:Smoke:test_ioManager_nextReady_text:0: Assertion 'data != -1' failed: data == -1, -1 == -1
Select is returning 0
after I use rewind
and fflush
.
When I use read
I can retreive the data.
// Debug
char bff[MAXLINE];
int n = read(inDescrp, bff, MAXLINE);
bff[n] = '\0';
printf("%d\n", inDescrp);
printf("%s\n", bff);
So select is returning 0
even when I can read data.
The problem also continues if I try to set a not zero timeout.
Why is this happening?
I need to check if a file is ready to be read.
What is a possible solution?
I can see why you have been led astray, by the 'nfds' parameter to select(). It reads and sounds like "number of file descriptors".
It is not that. It should be the value of the highest file descriptor that you care about, plus 1. See (for example) the Linux manpage about it
As an aside, the nfds parameter is an int - so don't use an unsigned short. It will "just work" generally, but is very confusing.