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

Viewed 178

I'm using Inotify (through the inotify-rs wrapper) to watch a large number of files (not directories) across a filesystem.

The following inotify-rs method returns a WatchDescriptor struct:

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

WatchDescriptor is a newtype struct: pub struct WatchDescriptor(RawFd); where std::os::unix::io::RawFd is type c_int/f32

the Inotify subsystem returns an inotify_event struct each time a watch is triggered:

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 */
    };

The "Watch descriptor" int wd matches the watch descriptor generated by the initial call to add_watch()

In turn, the inotify-rs wrapper returns the following event struct:

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

I am trying to use Event.wd to match the event to a file from a list of files being watched. (.name only returns a filename if the event triggered on a watch for a directory) I have been unsuccessful at trying to use a HashMap because the struct WatchDescriptor does not derive the Hash trait. I tried to fork the crate and implement that myself, but that opened up an entirely new can of worms.

The simplest way should be to use Event.wd.0 to get a c_int/i32 but then I have to deal with error: field '0' of struct 'inotify::WatchDescriptor' is private

Is there a simple way to do this, short of re-writing the wrapper to behave the way I want it, or to do a PR and wait for it to be merged?

I have considered creating an Inotify for each file being watched, but in a scenario where hundreds of files could be watched, this will be prohibitively expensive.

1 Answers
Related