/* called when the kernel has some events for us */ static void inotify_handler(struct tevent_context *ev, struct tevent_fd *fde, uint16_t flags, void *private_data) { struct inotify_private *in = talloc_get_type(private_data, struct inotify_private); int bufsize = 0; struct inotify_event *e0, *e; uint32_t prev_cookie=0; NTSTATUS status; /* we must use FIONREAD as we cannot predict the length of the filenames, and thus can't know how much to allocate otherwise */ if (ioctl(in->fd, FIONREAD, &bufsize) != 0 || bufsize == 0) { DEBUG(0,("No data on inotify fd?!\n")); TALLOC_FREE(fde); return; } e0 = e = (struct inotify_event *)TALLOC_SIZE(in, bufsize + 1); if (e == NULL) return; ((uint8_t *)e)[bufsize] = '\0'; status = read_data(in->fd, (char *)e0, bufsize); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("Failed to read all inotify data - %s\n", nt_errstr(status))); talloc_free(e0); /* the inotify fd will now be out of sync, * can't keep reading data off it */ TALLOC_FREE(fde); return; } /* we can get more than one event in the buffer */ while (e && (bufsize >= sizeof(*e))) { struct inotify_event *e2 = NULL; bufsize -= e->len + sizeof(*e); if (bufsize >= sizeof(*e)) { e2 = (struct inotify_event *)(e->len + sizeof(*e) + (char *)e); } inotify_dispatch(in, e, prev_cookie, e2); prev_cookie = e->cookie; e = e2; } talloc_free(e0); }
/* called when the kernel has some events for us */ static void inotify_handler(struct event_context *ev, struct fd_event *fde, uint16_t flags, void *private_data) { struct inotify_private *in = talloc_get_type(private_data, struct inotify_private); int bufsize = 0; struct inotify_event *e0, *e; uint32_t prev_cookie=0; /* we must use FIONREAD as we cannot predict the length of the filenames, and thus can't know how much to allocate otherwise */ if ((ioctl(in->fd, FIONREAD, &bufsize) != 0) && (errno == EACCES)) { /* * Workaround for broken SELinux policies on Fedora */ TALLOC_FREE(fde); in->broken_inotify = True; return; } if (bufsize == 0) { DEBUG(0,("No data on inotify fd?!\n")); return; } e0 = e = (struct inotify_event *)TALLOC_SIZE(in, bufsize); if (e == NULL) return; if (read(in->fd, e0, bufsize) != bufsize) { DEBUG(0,("Failed to read all inotify data\n")); talloc_free(e0); return; } /* we can get more than one event in the buffer */ while (bufsize >= sizeof(*e)) { struct inotify_event *e2 = NULL; bufsize -= e->len + sizeof(*e); if (bufsize >= sizeof(*e)) { e2 = (struct inotify_event *)(e->len + sizeof(*e) + (char *)e); } inotify_dispatch(in, e, prev_cookie, e2); prev_cookie = e->cookie; e = e2; } talloc_free(e0); }