diff options
Diffstat (limited to 'nslcd/inotify_helper.c')
-rw-r--r-- | nslcd/inotify_helper.c | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/nslcd/inotify_helper.c b/nslcd/inotify_helper.c new file mode 100644 index 0000000..dc1ae63 --- /dev/null +++ b/nslcd/inotify_helper.c @@ -0,0 +1,51 @@ +/* helper.h */ +#include <sys/inotify.h> /* for 'struct inotify_event' */ +#include <limits.h> /* for 'NAME_MAX' */ + +struct inotify_buffer { + ssize_t len; + ssize_t pos; + char dat[sizeof(struct inotify_event)+NAME_MAX+1]; +}; + +struct inotify_event *inotify_next_event_r(int fd, struct inotify_buffer *buf); +struct inotify_event *inotify_next_event(int fd); + +#define INOTIFY_ITERATOR(FD, EVENT) \ + struct inotify_event *EVENT = inotify_next_event(FD); \ + EVENT != NULL; \ + EVENT = inotify_next_event(FD) + +#define INOTIFY_ITERATOR_R(FD, EVENT, BUF) \ + struct inotify_event *EVENT = inotify_next_event_r(FD, BUF); \ + EVENT != NULL; \ + EVENT = inotify_next_event_r(FD, BUF) + +/* helper.c */ +#include <unistd.h> /* for read(3) */ + +#define EVENT_PTR(BUF) ((struct inotify_event *)&((BUF)->dat[(BUF)->pos])) +#define EVENT_SIZE(BUF) (sizeof(struct inotify_event) + EVENT_PTR(BUF)->len) + +struct inotify_event * +inotify_next_event_r(int fd, struct inotify_buffer *buf) { + if ((buf->len - buf->pos > sizeof(struct inotify_event)) + && (buf->len - buf->pos > EVENT_SIZE(buf))) { + buf->pos += EVENT_SIZE(buf); + } else { + do { + buf->len = read(FD, buf->dat, sizeof(buf->dat)); + } while (buf->len == 0); + BUF.pos = 0; + if (buf->len < 0) { + return NULL; + } + } + return EVENT_PTR(buf); +} + +struct inotify_event * +inotify_next_event(int fd) { + static struct inotify_buffer buf = { 0 }; + return inotify_next_event_r(fd, &buf); +} |