This is the code sample from “man select” plus a few lines to read an actual file which is being written to. I suspected that when the ./myfile.txt is written to, select would return that it can now read from that fd. But what happens is that select constantly returns in the while loop so long as the txt file exists. I want it to only return when new data is written to the end of the file. I thought that is how it should work.
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
int
main(void)
{
fd_set rfds;
struct timeval tv;
int retval;
int fd_file = open("/home/myfile.txt", O_RDONLY);
/* Watch stdin (fd 0) to see when it has input. */
FD_ZERO(&rfds);
FD_SET(0, &rfds);
FD_SET(fd_file, &rfds);
/* Wait up to five seconds. */
tv.tv_sec = 5;
tv.tv_usec = 0;
while (1)
{
retval = select(fd_file+1, &rfds, NULL, NULL, &tv);
/* Don't rely on the value of tv now! */
if (retval == -1)
perror("select()");
else if (retval)
printf("Data is available now.\n");
/* FD_ISSET(0, &rfds) will be true. */
else
printf("No data within five seconds.\n");
}
exit(EXIT_SUCCESS);
}
Disk files are always ready to read (but the read might return 0 bytes if you’re already at the end of the file), so you can’t use
select()on a disk file to find out when new data is added to the file.POSIX says:
Also, as cnicutar pointed out in a now-deleted post, in general, you have to initialize the FD_SET on each iteration. In your code, you are monitoring one fd, and that fd is always ready, so the FD_SET is not in fact changing. However, if you have 5 decriptors to monitor, and
selectdetects that only one is ready, then on the next iteration, only that one descriptor would be monitored (unless you reset the FD_SET). This makes usingselecttricky.