#include <stddef.h>
#include <sys/inotify.h>
+#include "log.h"
+
#define INOTIFY_EVENT_MAX (offsetof(struct inotify_event, name) + NAME_MAX + 1)
-#define FOREACH_INOTIFY_EVENT(e, buffer, sz) \
- for ((e) = &buffer.ev; \
- (uint8_t*) (e) < (uint8_t*) (buffer.raw) + (sz); \
- (e) = (struct inotify_event*) ((uint8_t*) (e) + sizeof(struct inotify_event) + (e)->len))
+#define _FOREACH_INOTIFY_EVENT(e, buffer, sz, log_level, start, end) \
+ for (struct inotify_event \
+ *start = &((buffer).ev), \
+ *end = (struct inotify_event*) ((uint8_t*) start + (sz)), \
+ *e = start; \
+ (uint8_t*) e + sizeof(struct inotify_event) <= (uint8_t*) end && \
+ (uint8_t*) e + sizeof(struct inotify_event) + e->len <= (uint8_t*) end ? true : \
+ ({ \
+ log_full(log_level, "Received invalid inotify event, ignoring."); \
+ false; \
+ }); \
+ e = (struct inotify_event*) ((uint8_t*) e + sizeof(struct inotify_event) + e->len))
+
+#define _FOREACH_INOTIFY_EVENT_FULL(e, buffer, sz, log_level) \
+ _FOREACH_INOTIFY_EVENT(e, buffer, sz, log_level, UNIQ_T(start, UNIQ), UNIQ_T(end, UNIQ))
+
+#define FOREACH_INOTIFY_EVENT(e, buffer, sz) \
+ _FOREACH_INOTIFY_EVENT_FULL(e, buffer, sz, LOG_DEBUG)
+
+#define FOREACH_INOTIFY_EVENT_WARN(e, buffer, sz) \
+ _FOREACH_INOTIFY_EVENT_FULL(e, buffer, sz, LOG_WARNING)
union inotify_event_buffer {
struct inotify_event ev;
for (;;) {
union inotify_event_buffer buffer;
- struct inotify_event *e;
ssize_t l;
if (timeout != USEC_INFINITY) {
for (;;) {
union inotify_event_buffer buffer;
- struct inotify_event *e;
ssize_t l;
l = read(fd, &buffer, sizeof(buffer));
return log_error_errno(errno, "Failed to read control group inotify events: %m");
}
- FOREACH_INOTIFY_EVENT(e, buffer, l) {
+ FOREACH_INOTIFY_EVENT_WARN(e, buffer, l) {
Unit *u;
if (e->wd < 0)
int path_spec_fd_event(PathSpec *s, uint32_t revents) {
union inotify_event_buffer buffer;
- struct inotify_event *e;
ssize_t l;
assert(s);
}
if (IN_SET(s->type, PATH_CHANGED, PATH_MODIFIED))
- FOREACH_INOTIFY_EVENT(e, buffer, l)
+ FOREACH_INOTIFY_EVENT_WARN(e, buffer, l)
if (s->primary_wd == e->wd)
return 1;
for (;;) {
union inotify_event_buffer buffer;
- struct inotify_event *e;
ssize_t l;
l = read(j->inotify_fd, &buffer, sizeof(buffer));
int sd_network_monitor_flush(sd_network_monitor *m) {
union inotify_event_buffer buffer;
- struct inotify_event *e;
ssize_t l;
int fd, k;
sd_event *event = sd_event_source_get_event(s);
ClockState *sp = userdata;
union inotify_event_buffer buffer;
- struct inotify_event *e;
ssize_t l;
l = read(fd, &buffer, sizeof(buffer));
return log_warning_errno(errno, "Lost access to inotify: %m");
}
- FOREACH_INOTIFY_EVENT(e, buffer, l)
+ FOREACH_INOTIFY_EVENT_WARN(e, buffer, l)
process_inotify_event(event, sp, e);
return 0;
static int on_inotify(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
Manager *manager = userdata;
union inotify_event_buffer buffer;
- struct inotify_event *e;
ssize_t l;
int r;
return log_error_errno(errno, "Failed to read inotify fd: %m");
}
- FOREACH_INOTIFY_EVENT(e, buffer, l) {
+ FOREACH_INOTIFY_EVENT_WARN(e, buffer, l) {
_cleanup_(sd_device_unrefp) sd_device *dev = NULL;
const char *devnode;