This question already has an answer here:
To explain more clearly what I want to do, I want my code to check if the user inputs something (or if another file descriptor than 0 has data to read) every (let's say) 2.5 seconds and so until the program stops.
If the user inputs something, a simple printf()
will notify him and then the program will check again if the user inputs something in the next 2,5 seconds.
Else, it should simply print that the time ran out and then check again for the user input in the next 2,5 seconds.
And here's the code snippet I stole from Beej's Guide to Network Programming and modified to (try to) fulfill my requirements:
#include <stdio.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#define STDIN 0 // file descriptor for standard input
int main(void){
struct timeval tv;
fd_set readfds;
FD_ZERO(&readfds);
FD_SET(STDIN, &readfds);
tv.tv_sec = 2;
tv.tv_usec = 500000;
while(1){
select(STDIN+1, &readfds, NULL, NULL, &tv);
if (FD_ISSET(STDIN, &readfds)){
printf("A key was pressed!\n");
tv.tv_sec = 2;
tv.tv_usec = 500000;
}else{
printf("Timed out.\n");
tv.tv_sec = 2;
tv.tv_usec = 500000;
}
}
return 0;
}
As long I don't press any key, this works fine and prints "Timed out." every 2,5 seconds. But if I enter something, it seems to ignore the user input and keeps printing "Timed out.".
On the other hand, if I declare the fd_set
and the struct timeval
inside the infinite loop, once I enter something, this prints infinitely that a key has been pressed as if it ignores the timeout.
I have no idea why such a simple code doesn't work. I guess I'm missing some point about file descriptors I don't know about.
Because you should reset ->
FD_ZERO(&readfds)
yourreadfds
and add the file desciptor ->FD_SET(STDIN, &readfds)
every timeselect
returns, since on timeout the file descriptor is removed from the setas you see you should also check the return value from
select
, to check for an error, in case of an error, then checkerrno
to see what happened, and then you check it the file descritor you're interested in is contained inreadfds
.