Example #1
0
bool process_inotify_input() {
  ssize_t len = read(inotify_fd, event_buf, EVENT_BUF_LEN);
  if (len < 0) {
    userlog(LOG_ERR, "read: %s", strerror(errno));
    return false;
  }

  int i = 0;
  while (i < len) {
    struct inotify_event* event = (struct inotify_event*) &event_buf[i];
    i += EVENT_SIZE + event->len;

    if (event->mask & IN_IGNORED) {
      continue;
    }
    if (event->mask & IN_Q_OVERFLOW) {
      userlog(LOG_INFO, "event queue overflow");
      continue;
    }

    if (!process_inotify_event(event)) {
      return false;
    }
  }

  return true;
}
Example #2
0
static bool inot_root_consume_notify(watchman_global_watcher_t watcher,
    w_root_t *root, struct watchman_pending_collection *coll)
{
  struct inot_root_state *state = root->watch;
  struct inotify_event *ine;
  char *iptr;
  int n;
  struct timeval now;
  unused_parameter(watcher);

  n = read(state->infd, &state->ibuf, sizeof(state->ibuf));
  if (n == -1) {
    if (errno == EINTR) {
      return false;
    }
    w_log(W_LOG_FATAL, "read(%d, %zu): error %s\n",
        state->infd, sizeof(state->ibuf), strerror(errno));
  }

  w_log(W_LOG_DBG, "inotify read: returned %d.\n", n);
  gettimeofday(&now, NULL);

  for (iptr = state->ibuf; iptr < state->ibuf + n;
      iptr = iptr + sizeof(*ine) + ine->len) {
    ine = (struct inotify_event*)iptr;

    process_inotify_event(root, coll, ine, now);

    if (root->cancelled) {
      return false;
    }
  }

  // It is possible that we can accumulate a set of pending_move
  // structs in move_map.  This happens when a directory is moved
  // outside of the watched tree; we get the MOVE_FROM but never
  // get the MOVE_TO with the same cookie.  To avoid leaking these,
  // we'll age out the move_map after processing a full set of
  // inotify events.   We age out rather than delete all because
  // the MOVE_TO may yet be waiting to read in another go around.
  // We allow a somewhat arbitrary but practical grace period to
  // observe the corresponding MOVE_TO.
  if (w_ht_size(state->move_map) > 0) {
    w_ht_iter_t iter;
    if (w_ht_first(state->move_map, &iter)) do {
      struct pending_move *pending = w_ht_val_ptr(iter.value);
      if (now.tv_sec - pending->created > 5 /* seconds */) {
        w_log(W_LOG_DBG,
            "deleting pending move %s (moved outside of watch?)\n",
            pending->name->buf);
        w_ht_iter_del(state->move_map, &iter);
      }
    } while (w_ht_next(state->move_map, &iter));
  }

  return true;
}
static int inotify_handler(sd_event_source *s,
                           int fd,
                           uint32_t revents,
                           void *userdata) {
        sd_event *event = sd_event_source_get_event(s);
        ClockState *sp = userdata;
        union inotify_event_buffer buffer;
        struct inotify_event *e;
        ssize_t l;

        l = read(fd, &buffer, sizeof(buffer));
        if (l < 0) {
                if (IN_SET(errno, EAGAIN, EINTR))
                        return 0;

                return log_warning_errno(errno, "Lost access to inotify: %m");
        }
        FOREACH_INOTIFY_EVENT(e, buffer, l)
                process_inotify_event(event, sp, e);

        return 0;
}