5

考虑以下代码片段。

#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;
}

这个程序接收一个文件名,打开相应的文件,并“轮询”它的文件描述符,以便监控数据的可用性。每当poll检测到可用数据时,就会打印这些新数据。

但是,这个程序会发生什么?如果我要监视的文件在程序启动时已经包含数据,则会打印其内容。没关系。但是,后来,当我使用文本编辑器编辑文件并保存它时,我的程序不会打印新数据。

那么,如何监视常规文件描述符(而不是使用其路径的文件)以获取新数据?我必须使用除 之外的其他功能poll吗?还是我错过了任何pollfd标志?

4

1 回答 1

6

您不能poll在常规文件上使用来监视更改。但是,还有其他几种方法。fstat经典的方法是使用打开的文件描述符定期调用,并将返回的字段与之前的字段(特别是st_size)进行比较。一种现代方法是inotify(7)用于监视文件。例如,最新版本的 GNU tail 使用这种方法:

$ 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, ...

有关其工作原理的更多信息,请参阅手册页inotify(7)

于 2013-06-16T15:03:53.073 回答