summaryrefslogtreecommitdiff
path: root/src/path.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2010-10-13 02:34:00 +0200
committerLennart Poettering <lennart@poettering.net>2010-10-13 02:34:00 +0200
commitf601daa70143745915a8d38603969f228414af19 (patch)
treee0e2109a3ca1eaead2dc71769b989832a1001278 /src/path.c
parent52661efd21608dc7e0ac26b714a9254ed6180ddb (diff)
inotify: properly handle multiple inotify events per read()
Diffstat (limited to 'src/path.c')
-rw-r--r--src/path.c27
1 files changed, 17 insertions, 10 deletions
diff --git a/src/path.c b/src/path.c
index 92f99381e8..b3bc8a5a0d 100644
--- a/src/path.c
+++ b/src/path.c
@@ -453,7 +453,8 @@ static void path_fd_event(Unit *u, int fd, uint32_t events, Watch *w) {
Path *p = PATH(u);
int l;
ssize_t k;
- struct inotify_event *buf = NULL;
+ uint8_t *buf = NULL;
+ struct inotify_event *e;
PathSpec *s;
assert(p);
@@ -493,16 +494,22 @@ static void path_fd_event(Unit *u, int fd, uint32_t events, Watch *w) {
goto fail;
}
- if ((size_t) k < sizeof(struct inotify_event) ||
- (size_t) k < sizeof(struct inotify_event) + buf->len) {
- log_error("inotify event too small.");
- goto fail;
- }
+ e = (struct inotify_event*) buf;
- if (s->type == PATH_CHANGED && s->primary_wd == buf->wd)
- path_enter_running(p);
- else
- path_enter_waiting(p, false);
+ while (k > 0) {
+ size_t step;
+
+ if (s->type == PATH_CHANGED && s->primary_wd == e->wd)
+ path_enter_running(p);
+ else
+ path_enter_waiting(p, false);
+
+ step = sizeof(struct inotify_event) + e->len;
+ assert(step <= (size_t) k);
+
+ e = (struct inotify_event*) ((uint8_t*) e + step);
+ k -= step;
+ }
free(buf);