Reputation: 2991
Consider the following code snippet.
#include <fcntl.h>
#include <stdio.h>
#include <sys/poll.h>
#include <unistd.h>
int main(int argc, char ** argv) {
int fd;
char buf[1024];
int i;
struct pollfd pfds;
fd = open(argv[1], O_RDONLY);
while (1) {
pfds.fd = fd;
pfds.events = POLLIN;
poll(&pfds, 1, -1);
if (pfds.revents & POLLIN) {
i = read(fd, buf, 1024);
write(1, buf, i);
}
}
return 0;
}
This program receives a file name, opens the corresponding file, and "poll"s its file descriptor in order to monitor data in availability. Whenever poll
detects data in availability, those new data are printed.
However, what happens with this program? If the file I want to monitor already contained data when the program is launched, its contents are printed. That's ok. But, later, when I edit the file with a text editor and save it, my program doesn't print the new data.
So, how to monitor a regular file descriptor (not a file using its path) for new data availability? Do I have to use another function other than poll
? Or am I missing any pollfd
flag?
Upvotes: 5
Views: 2665
Reputation: 50094
You can't use poll
on regular files to watch for changes. However, there are several other ways. The classic approach is to call fstat
at regular intervals with the open file descriptor, and compare the returned fields with the previous fields (in particular st_size
). A modern approach is to use inotify(7)
for monitoring files. For example recent versions of GNU tail use this approach:
$ strace tail -f /tmp/foobar
...
open("/tmp/foobar", O_RDONLY) ) = 3
...
inotify_init() = 4
inotify_add_watch(4, "/tmp/foobar", IN_MODIFY|IN_ATTRIB|IN_DELETE_SELF|IN_MOVE_SELF) = 1
...
read(4, ...
See the manual page inotify(7) for more information on how that works.
Upvotes: 6