summaryrefslogtreecommitdiff
path: root/src/util.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/util.c
parent52661efd21608dc7e0ac26b714a9254ed6180ddb (diff)
inotify: properly handle multiple inotify events per read()
Diffstat (limited to 'src/util.c')
-rw-r--r--src/util.c32
1 files changed, 20 insertions, 12 deletions
diff --git a/src/util.c b/src/util.c
index d09e447776..434f311e71 100644
--- a/src/util.c
+++ b/src/util.c
@@ -2247,26 +2247,34 @@ int acquire_terminal(const char *name, bool fail, bool force, bool ignore_tiocst
assert(notify >= 0);
for (;;) {
- struct inotify_event e;
+ uint8_t inotify_buffer[sizeof(struct inotify_event) + FILENAME_MAX];
ssize_t l;
+ struct inotify_event *e;
- if ((l = read(notify, &e, sizeof(e))) != sizeof(e)) {
+ if ((l = read(notify, &inotify_buffer, sizeof(inotify_buffer))) < 0) {
- if (l < 0) {
+ if (errno == EINTR)
+ continue;
- if (errno == EINTR)
- continue;
+ r = -errno;
+ goto fail;
+ }
+
+ e = (struct inotify_event*) inotify_buffer;
- r = -errno;
- } else
+ while (l > 0) {
+ size_t step;
+
+ if (e->wd != wd || !(e->mask & IN_CLOSE)) {
r = -EIO;
+ goto fail;
+ }
- goto fail;
- }
+ step = sizeof(struct inotify_event) + e->len;
+ assert(step <= (size_t) l);
- if (e.wd != wd || !(e.mask & IN_CLOSE)) {
- r = -EIO;
- goto fail;
+ e = (struct inotify_event*) ((uint8_t*) e + step);
+ l -= step;
}
break;