bool PendingCollectionBase::add( struct watchman_dir* dir, const char* name, struct timeval now, int flags) { return add(w_dir_path_cat_str(dir, name), now, flags); }
static bool kqueue_root_start_watch_file( w_root_t *root, struct watchman_file *file) { struct kqueue_root_state *state = root->watch; struct kevent k; w_ht_val_t fdval; int fd; w_string_t *full_name; full_name = w_dir_path_cat_str(file->parent, w_file_get_name(file)); pthread_mutex_lock(&state->lock); if (w_ht_lookup(state->name_to_fd, w_ht_ptr_val(full_name), &fdval, false)) { // Already watching it pthread_mutex_unlock(&state->lock); w_string_delref(full_name); return true; } pthread_mutex_unlock(&state->lock); w_log(W_LOG_DBG, "watch_file(%s)\n", full_name->buf); fd = open(full_name->buf, O_EVTONLY|O_CLOEXEC); if (fd == -1) { w_log(W_LOG_ERR, "failed to open %s O_EVTONLY: %s\n", full_name->buf, strerror(errno)); w_string_delref(full_name); return false; } memset(&k, 0, sizeof(k)); EV_SET(&k, fd, EVFILT_VNODE, EV_ADD|EV_CLEAR, NOTE_WRITE|NOTE_DELETE|NOTE_EXTEND|NOTE_RENAME|NOTE_ATTRIB, 0, full_name); pthread_mutex_lock(&state->lock); w_ht_replace(state->name_to_fd, w_ht_ptr_val(full_name), fd); w_ht_replace(state->fd_to_name, fd, w_ht_ptr_val(full_name)); pthread_mutex_unlock(&state->lock); if (kevent(state->kq_fd, &k, 1, NULL, 0, 0)) { w_log(W_LOG_DBG, "kevent EV_ADD file %s failed: %s", full_name->buf, strerror(errno)); close(fd); pthread_mutex_lock(&state->lock); w_ht_del(state->name_to_fd, w_ht_ptr_val(full_name)); w_ht_del(state->fd_to_name, fd); pthread_mutex_unlock(&state->lock); } else { w_log(W_LOG_DBG, "kevent file %s -> %d\n", full_name->buf, fd); } w_string_delref(full_name); return true; }