Inotify read single event

Viewed 153

I have an app that registers multiple inotify watches on the same inotify fd. Due to the way the app is structured, I need events to be read one-by-one (instead of a single read(2) possibly returning multiple events), but so far I haven't found a way to do so.

Originally I tried to read the event head struct inotify_event, then read the rest of the event's data according to the .len field. But read(2) on an inotify fd shall fail with EINVAL if the supplied buffer is too small, as described in the man page:

 The behavior when the buffer given to read(2) is too small to return
 information about the next event depends on the kernel version: in
 kernels before 2.6.21, read(2) returns 0; since kernel 2.6.21,
 read(2) fails with the error EINVAL. 

Looking in the source, the implementation of read will try to return as many events as it can given the buffer size passed to it. As can be seen here, given a successful copy of one event, it will continue the loop, trying to copy more events if present.

I also considered the possibility of using ioctl(FIONREAD), but it returns the total size of all queued events, not just one (well, as expected...)

My best shot at it, currently, is to start with read(..., sizeof(struct inotify_event)). If that fails with EINVAL, try read(..., sizeof(struct inotify_event) * 2 - 1), then with sizeof(struct inotify_event) * 3 - 1 and so forth. That will be the least number of syscalls to achieve a read of a single event, without knowing its size beforehand. Obviously, though, it's not optimal.

Is there any better way to achieve a single read?

0 Answers
Related