summaryrefslogtreecommitdiff
path: root/common/inotify_helpers.h
diff options
context:
space:
mode:
Diffstat (limited to 'common/inotify_helpers.h')
-rw-r--r--common/inotify_helpers.h80
1 files changed, 80 insertions, 0 deletions
diff --git a/common/inotify_helpers.h b/common/inotify_helpers.h
new file mode 100644
index 0000000..5bb7647
--- /dev/null
+++ b/common/inotify_helpers.h
@@ -0,0 +1,80 @@
+/* inotify_helper.h - Simple iteration for inotify events
+ *
+ * Copyright (C) 2014 Luke Shumaker
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* The usage is pretty simple:
+ *
+ * int my_filedesc = inotify_init();
+ * ...
+ * struct inotify_event *my_event;
+ * for (INOTIFY_ITR(my_filedesc, my_event)) {
+ * ...
+ * }
+ *
+ * Easy, right?
+ */
+
+#ifndef _INOTIFY_HELPER_H
+#define _INOTIFY_HELPER_H
+
+#include <sys/inotify.h>
+#include <limits.h> /* for NAME_MAX */
+#include <string.h> /* for memset(3) */
+#include <unistd.h> /* for read(3) */
+
+struct _inotify_buffer {
+ ssize_t len;
+ ssize_t pos;
+ char dat[sizeof(struct inotify_event)+NAME_MAX+1];
+};
+
+#define _INOTIFY_ITR_EVENT(BUF) \
+ ((struct inotify_event *)&((BUF).dat[(BUF).pos]))
+#define _INOTIFY_ITR_EVENT_SIZE(BUF) \
+ (sizeof(struct inotify_event) + _INOTIFY_ITR_EVENT(BUF)->len)
+
+#define _INOTIFY_ITR_INIT(FD, BUF, EVENT) \
+ struct _inotify_buffer BUF = ({ \
+ struct _inotify_buffer tmp; \
+ memset(&tmp, 0, sizeof(tmp)); \
+ do { \
+ tmp.len = read(FD, tmp.dat, sizeof(tmp.dat)); \
+ } while (tmp.len == 0); \
+ EVENT = (struct inotify_event *)&BUF; \
+ tmp; \
+ })
+#define _INOTIFY_ITR_CHECK(FD, BUF, EVENT) \
+ BUF.len > -1
+#define _INOTIFY_ITR_UPDATE(FD, BUF, EVENT) \
+ EVENT = ({ \
+ if (BUF.len-(BUF.pos+_INOTIFY_ITR_EVENT_SIZE(BUF)) < 1) { \
+ do { \
+ BUF.len = read(FD, BUF.dat, sizeof(BUF.dat)); \
+ } while (BUF.len == 0); \
+ BUF.pos = 0; \
+ } else { \
+ BUF.pos += _INOTIFY_ITR_EVENT_SIZE(BUF); \
+ } \
+ _INOTIFY_ITR_EVENT(BUF); \
+ })
+
+#define INOTIFY_ITR(FD, EVENT) \
+ _INOTIFY_ITR_INIT(FD, _buf, EVENT); \
+ _INOTIFY_ITR_CHECK(FD, _buf, EVENT); \
+ _INOTIFY_ITR_UPDATE(FD, _buf, EVENT)
+
+#endif