如何在 C 中使用 inotify?

Posted

技术标签:

【中文标题】如何在 C 中使用 inotify?【英文标题】:How to use inotify in C? 【发布时间】:2013-03-11 23:08:26 【问题描述】:

我搜索了inotify相关的问题,这个有点不一样……

我使用下面的代码来监控一个文件(不是目录)的变化。在测试中,当我保存目标文件时 read() 确实返回,这意味着它可以工作。但是 event->mask 是 32768 ,它不是 IN_MODIFY 并且名称为空。另一个问题:它无法连续监控。当我第二次更改文件时,它没有响应。感谢您的帮助!

#include <sys/inotify.h>
#include <unistd.h>
#include <stdio.h>

#define EVENT_SIZE  (sizeof (struct inotify_event))
#define BUF_LEN        (16 * (EVENT_SIZE + 16))

int main()

    int fd;
    fd = inotify_init();
    if (fd < 0)
        perror("inotify_init()");

    int wd;
    wd = inotify_add_watch(fd, "target.txt", IN_MODIFY);
    if (wd < 0)
        perror("inotify_add_watch");

    char buf[BUF_LEN];
    int len;

start:

    len = read(fd, buf, BUF_LEN);

    if (len > 0)
    
        int i = 0;
        while (i < len)
        
            struct inotify_event *event;
            event = (struct inotify_event *) &buf[i];

            printf("wd=%d mask=%x cookie=%u len=%u\n",
                event->wd, event->mask,
                event->cookie, event->len);

            if (event->mask & IN_MODIFY)
                printf("file modified %s", event->name);

            if (event->len)
                printf("name=%s\n", event->name);

            i += EVENT_SIZE + event->len;
        
    

    goto start;

    return 0;

【问题讨论】:

【参考方案1】:

0x8000 对应于IN_IGNORED。它在掩码中的存在表明 inotify 监视已被删除,因为文件已被删除。您的编辑器可能删除了旧文件并在其位置放置了一个新文件。再次更改文件没有效果,因为手表已被移除。

没有返回名称,因为您没有查看目录。

来自inotify man page。

name 字段仅在为监视目录中的文件返回事件时出现;它标识相对于监视目录的文件路径名。

...

IN_IGNORED -- 显式删除监视 (inotify_rm_watch(2)) 或自动删除(文件已删除,或文件系统已卸载)。

【讨论】:

知道了,谢谢!我确实观察到使用 vim 和 cat 修改目标文件之间的不同行为。对于监控文件,可以使用 wd 来检索文件名。【参考方案2】:

event->mask 32768 相当于 0x8000 即 IN_IGNORED 更多信息:“/usr/include/linux/inotify.h”

    if (event->mask & IN_IGNORED) 
        /*Remove watch*/ inotify_rm_watch(fileDescriptor,watchDescriptor)
        /*Add watch again*/ inotify_add_watch
    

【讨论】:

以上是关于如何在 C 中使用 inotify?的主要内容,如果未能解决你的问题,请参考以下文章

C语言中的inotify文件

如何在 PHP7.4 中使用 inotify

inotify - 最好的方法是啥?

如何在功能测试中模拟 INotify 失败?

如何监视文件并在终端中打印出更改(使用 inotify)?

如何使用 Inotify 和 libev 在文件夹中获取新添加的文件?