#define AL_LOG_SECTION "fs_event" #include #include "../util/error.h" #include "../socket/socket.h" #include "fs_event.h" #define EVENT_MAX_SIZE (sizeof(struct inotify_event) + NAME_MAX + 1) static void event_callback(struct ev_loop *loop, ev_io *w, s32 revents) { (void)loop; struct nn_fs_event *fs = (struct nn_fs_event *)w->data; (void)revents; struct inotify_event *event = al_malloc(EVENT_MAX_SIZE); ssize_t ret = nn_read(fs->fd, event, EVENT_MAX_SIZE); al_assert(ret > 0); if (!(event->mask & fs->mask)) { al_assert(event->mask & IN_IGNORED); return; } al_assert(event->wd == fs->wd); fs->callback(fs->userdata, event); al_free(event); } void nn_fs_event_init(struct nn_fs_event *fs, str *path, u32 mask, void (*callback)(void *, struct inotify_event *), void *userdata) { fs->fd = inotify_init(); nn_fd_set_blocking(fs->fd, true); fs->path = al_str_to_c_str(path); fs->mask = mask; fs->callback = callback; fs->userdata = userdata; fs->event.data = fs; ev_io_init_n(&fs->event, event_callback, fs->fd, EV_READ); } bool nn_fs_event_start(struct nn_fs_event *fs, struct nn_event_loop *loop) { fs->loop = loop; fs->wd = inotify_add_watch(fs->fd, fs->path, fs->mask); if (fs->wd == -1) { log_error("inotify_add_watch(%s) failed (%s).", fs->path, nn_strerror(errno)); return false; } ev_io_start(fs->loop->ev, &fs->event); return true; } void nn_fs_event_stop(struct nn_fs_event *fs) { inotify_rm_watch(fs->fd, fs->wd); ev_io_stop(fs->loop->ev, &fs->event); } void nn_fs_event_free(struct nn_fs_event *fs) { close(fs->fd); al_free(fs->path); }