예제 #1
0
/*
  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);
}
예제 #2
0
/*
  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);
}