如何使用 inotify-rs 生成的 WatchDescriptor 结构将事件与生成它们的文件匹配?

How do I use the WatchDescriptor struct generated by inotify-rs to match events to files that generated them?

我正在使用 Inotify(通过 inotify-rs 包装器)来监视文件系统中的大量文件(不是目录)。

下面的inotify-rs方法returns一个WatchDescriptor结构:

add_watch<P>(&mut self, path: P, mask: WatchMask) -> io::Result<WatchDescriptor>
where
   P: AsRef<Path>

WatchDescriptor 是新类型结构:pub struct WatchDescriptor(RawFd); 其中 std::os::unix::io::RawFd 是类型 c_int/f32

Inotify 子系统 returns 每次触发监视时 inotify_event 结构:

struct inotify_event {
        int      wd;       /* Watch descriptor */
        uint32_t mask;     /* Mask describing event */
        uint32_t cookie;   /* Unique cookie associating related
                                events (for rename(2)) */
        uint32_t len;      /* Size of name field */
        char     name[];   /* Optional null-terminated name */
    };

"Watch descriptor" int wd 与初始调用 add_watch()

生成的监视描述符相匹配

反过来,inotify-rs 包装器 returns 以下事件结构:

pub struct Event<'a> {    
    pub wd    : WatchDescriptor,
    pub mask  : EventMask,
    pub cookie: u32,
    pub name  : &'a OsStr,
}

我正在尝试使用 Event.wd 将事件与正在监视的文件列表中的文件相匹配。 (.name 只有 returns 一个文件名,如果事件在监视目录时触发)我尝试使用 HashMap 没有成功,因为结构 WatchDescriptor 没有派生Hash 特征。我试图 fork 这个箱子并自己实现它,但这打开了一个全新的蠕虫罐头。

最简单的方法应该是使用 Event.wd.0 来获得 c_int/i32 但是我必须处理 error: field '0' of struct 'inotify::WatchDescriptor' is private

有没有一种简单的方法可以做到这一点,而不是重写包装器以按照我想要的方式运行,或者做一个 PR 并等待它被合并?

我考虑过为每个正在观看的文件创建一个 Inotify,但是在可以观看数百个文件的情况下,这将非常昂贵。

此库存在一些重大问题:

  • 表示 inotify 监视描述符的类型选择不当。 Inotify 监视描述符是 而不是 Unix 文件描述符,它们只是一些整数,每个 inotify 文件描述符的作用域。这本身并不是一个缺陷,但我当然会将其视为危险信号。
  • 如上所述,inotify 监视描述符值的范围是每个父 inotify 文件描述符。这使得在 WatchDescriptor 上使用 [derive(Eq)] 非常值得怀疑。看起来像一个直接的错误。
  • 没有什么可以确保在关闭 inotify 描述符之前关闭 inotify watches。没有什么可以确保监视描述符不会在您的背后被重用(它们可以在监视描述符编号回绕后重用)。这些问题可能不会立即困扰您,但是……IMO,应该声明整个 inotify-rs unsafe。它不会在 inotify 之上添加任何实际的安全性,只是一些糖和无意义的包装。它甚至没有为监视描述符实现 Drop
  • 该库没有突出 inotify 的主要陷阱:事件队列溢出,IN_IGNORED 和硬链接共享相同的 inode(以及相同的 inotify 监视描述符!)

我建议您仔细阅读 inotify 文档并在必要时编写自己的包装器。这个库不会为你省去任何麻烦。