inotify_add_watch 相对于 O_PATH dirfd

Posted

技术标签:

【中文标题】inotify_add_watch 相对于 O_PATH dirfd【英文标题】:inotify_add_watch relative to O_PATH dirfd 【发布时间】:2017-02-08 06:25:17 【问题描述】:

我正在尝试致电inotify_add_watch 来观看文件。我想指定相对于 O_PATH | 的文件O_DIRECTORY 文件描述符,例如 symlinkat、fstatat 或 openat。

这可能吗?它看起来不像。有人知道解决方法吗?

编辑

最接近的似乎是man 2 open 在“openat 的基本原理”下描述的“技巧”。示例见 user1643723 的回答。

【问题讨论】:

你试过(ab)使用 procfs 吗?当您想模拟 XXXat 系统调用的功能时,尝试/proc/self/fd/<dir descriptor>/filename 总是一个好主意。 当我使用像 /proc/self/fd/6/foo 这样的传递路径到 inotify_add_watch 时,我得到了 ENOTDIR 您的代码中存在某种错误。要么您过早关闭目录描述符,要么您一开始就没有使用正确的描述符。请参阅我对工作代码的回答。 【参考方案1】:

您可以使用 procfs 提供的符号链接来实现大多数 *at 调用的功能。打开目录描述符并使用/proc/self/fd/<dir descriptor>/filename 而不是文件名的完整路径:

#define _GNU_SOURCE

#include <sys/stat.h>
#include <sys/inotify.h>
#include <sys/types.h>

#include <fcntl.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>

int main() 
    int inotify = inotify_init();

    mkdir("tmp", 0777);
    mknod("tmp/foo", 0777 | S_IFREG, 0);

    int dirFd = open("tmp", O_DIRECTORY | O_PATH);

    char buf[40] =  '\0' ;

    sprintf(buf, "/proc/self/fd/%d/foo", dirFd);

    int watchd = inotify_add_watch(inotify, buf, IN_MOVE | IN_ATTRIB);

    if (watchd < 0) 
        printf("Failed: %s", strerror(errno));
     else 
        printf("ok");
    

上面的程序在 Linux 4.4.x 上打印“ok”。

【讨论】:

你没有使用过 O_PATH。我还需要能够将此文件描述符传递给正确的 *at 系统调用(如 fstatat 等)。 抱歉,我更新了代码以使用 O_PATH。对我来说仍然很好。请注意,您没有必须将 O_PATH 与 *at 系统调用一起使用——它们只需使用普通文件描述符查找即可。 我猜这是man7.org/linux/man-pages/man2/open.2.html 在基本原理下描述的“技巧”。仍然坚持正确的 *at 支持 inotify。

以上是关于inotify_add_watch 相对于 O_PATH dirfd的主要内容,如果未能解决你的问题,请参考以下文章

推送到 bitbucket 时出现错误“inotify_add_watch”

inotify,inotify_add_watch() 监控多个目录,c++

为啥需要使用 inotify_add_watch() 调用 read() 两次

inotify_add_watch 失败,没有这样的文件或目录

Docker 守护进程无法启动:inotify_add_watch: no such file or directory

QInotifyFileSystemWatcherEngine::addPaths: inotify_add_watch failed: 设备上没有空间