summaryrefslogtreecommitdiff
path: root/nslcd/inotify_helper.c
diff options
context:
space:
mode:
Diffstat (limited to 'nslcd/inotify_helper.c')
-rw-r--r--nslcd/inotify_helper.c51
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);
+}