1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
|
#define AL_LOG_SECTION "fs_event"
#include <al/log.h>
#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);
}
|