November 16th, 2007

inotify surprise

I'm throwing together a bit of Lisp glue to access inotify(7). Part of the interface involves reading binary structures from a file descriptor. The structures look like this:

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

"Aha!" I thought, "I'll read() the first four fields into a small buffer, then use the len field to read the name into a buffer of the exactly right length."

This doesn't work. inotify.txt says that a read() will return as many events that will fit into the buffer. If your buffer is too small to fit a complete event structure, you'll get a zero-length read.

Instead of reading partial events, the documentation suggests using the FIONREAD ioctl to see how many octets are available to read from the inotify fd. That isn't quite as nice as being able to precisely read only the next event, but I guess it'll do.