如何监测文件描述符是否有新数据可用?

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”检测到有新数据可用时,这些新数据就会被打印出来。
然而,如果我想要监视的文件在程序启动时已经包含数据,那么它的内容会被打印出来。这没问题。但是,稍后当我用文本编辑器编辑并保存该文件时,我的程序并不会打印新的数据。
那么,如何监视常规文件描述符(而不是使用其路径的文件)以获取新的数据可用性?我需要使用其他函数来代替“poll”吗?或者我错过了任何“pollfd”标志吗?

也许你应该调用fstat并检查EBADF,但首先查看poll系统调用的返回值会更有帮助! - Brett Hale
“poll” 对于普通磁盘文件无效。 - n. m.
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)以获取有关其工作原理的更多信息。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接