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.