Skip to content

Instantly share code, notes, and snippets.

@croepha
Last active November 17, 2017 02:17
Show Gist options
  • Save croepha/fa234c8e74b35e27fe8396481ce2f4ce to your computer and use it in GitHub Desktop.
Save croepha/fa234c8e74b35e27fe8396481ce2f4ce to your computer and use it in GitHub Desktop.
// Example of how to watch files on BSD/OSX, with a timer thrown in for fun
#define MAIN_WATCH "file1"
#define ALTERNATING_WATCH "file2"
#include <stdio.h>
#include <assert.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/event.h>
struct MyWatchContext {
char* path;
int fd;
};
void add_watch(int queue_fd, MyWatchContext* ctx) {
ctx->fd = open(ctx->path, O_EVTONLY);
assert(ctx->fd > 0);
struct kevent queue_change;
printf("add %d\n", ctx->fd);
EV_SET(&queue_change, ctx->fd,
EVFILT_VNODE, EV_ADD | EV_CLEAR | EV_RECEIPT,
NOTE_DELETE | NOTE_WRITE | NOTE_RENAME | NOTE_REVOKE,
0, ctx);
int kr = kevent(queue_fd, &queue_change, 1, NULL, NULL, NULL);
assert(kr==0);
}
void del_watch(MyWatchContext* ctx) {
close(ctx->fd);
}
void add_timer(int queue_fd, int id, int ms) {
struct kevent queue_change;
EV_SET(&queue_change, id,
EVFILT_TIMER, EV_ADD | EV_ONESHOT | EV_RECEIPT, 0, ms, NULL);
int kr = kevent(queue_fd, &queue_change, 1, NULL, NULL, NULL);
assert(kr==0);
}
int main(int argc, char *argv[]) {
int queue_fd = kqueue();
assert(queue_fd > 0);
MyWatchContext main_watch_ctx = { MAIN_WATCH };
MyWatchContext alt_watch_ctx = { ALTERNATING_WATCH };
bool alt_status = false;
add_watch(queue_fd, &main_watch_ctx);
add_watch(queue_fd, &alt_watch_ctx);
add_timer(queue_fd, 10, 10000);
for (;;) {
struct kevent event_to_handle = {};
int r1 = kevent(queue_fd, NULL, 0, &event_to_handle, 1, NULL);
assert(r1 == 1);
if (event_to_handle.udata == NULL) {
assert(event_to_handle.ident == 10);
printf("got_timer\n");
if (alt_status) {
add_watch(queue_fd, &alt_watch_ctx);
} else {
del_watch(&alt_watch_ctx);
}
alt_status = !alt_status;
add_timer(queue_fd, 10, 10000);
} else {
MyWatchContext*ctx = (MyWatchContext *)event_to_handle.udata;
printf("Got event for file: %s\n", ctx->path);
}
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment