Last active
November 17, 2017 02:17
-
-
Save croepha/fa234c8e74b35e27fe8396481ce2f4ce to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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