mirror of
https://github.com/systemd/systemd.git
synced 2025-01-10 05:18:17 +03:00
inotify: properly handle multiple inotify events per read()
This commit is contained in:
parent
52661efd21
commit
f601daa701
2
TODO
2
TODO
@ -68,8 +68,6 @@
|
|||||||
|
|
||||||
* ask-password tty timeout
|
* ask-password tty timeout
|
||||||
|
|
||||||
* properly handle multiple inotify events per read() in path.c and util.c
|
|
||||||
|
|
||||||
* readahead: btrfs/LVM SSD detection
|
* readahead: btrfs/LVM SSD detection
|
||||||
|
|
||||||
* document locale.conf, vconsole.conf and possibly the tempfiles.d and modules-load.d mechanism.
|
* document locale.conf, vconsole.conf and possibly the tempfiles.d and modules-load.d mechanism.
|
||||||
|
27
src/path.c
27
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);
|
Path *p = PATH(u);
|
||||||
int l;
|
int l;
|
||||||
ssize_t k;
|
ssize_t k;
|
||||||
struct inotify_event *buf = NULL;
|
uint8_t *buf = NULL;
|
||||||
|
struct inotify_event *e;
|
||||||
PathSpec *s;
|
PathSpec *s;
|
||||||
|
|
||||||
assert(p);
|
assert(p);
|
||||||
@ -493,16 +494,22 @@ static void path_fd_event(Unit *u, int fd, uint32_t events, Watch *w) {
|
|||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((size_t) k < sizeof(struct inotify_event) ||
|
e = (struct inotify_event*) buf;
|
||||||
(size_t) k < sizeof(struct inotify_event) + buf->len) {
|
|
||||||
log_error("inotify event too small.");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (s->type == PATH_CHANGED && s->primary_wd == buf->wd)
|
while (k > 0) {
|
||||||
path_enter_running(p);
|
size_t step;
|
||||||
else
|
|
||||||
path_enter_waiting(p, false);
|
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);
|
free(buf);
|
||||||
|
|
||||||
|
34
src/util.c
34
src/util.c
@ -2247,26 +2247,34 @@ int acquire_terminal(const char *name, bool fail, bool force, bool ignore_tiocst
|
|||||||
assert(notify >= 0);
|
assert(notify >= 0);
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
struct inotify_event e;
|
uint8_t inotify_buffer[sizeof(struct inotify_event) + FILENAME_MAX];
|
||||||
ssize_t l;
|
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;
|
|
||||||
} else
|
|
||||||
r = -EIO;
|
|
||||||
|
|
||||||
|
r = -errno;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e.wd != wd || !(e.mask & IN_CLOSE)) {
|
e = (struct inotify_event*) inotify_buffer;
|
||||||
r = -EIO;
|
|
||||||
goto fail;
|
while (l > 0) {
|
||||||
|
size_t step;
|
||||||
|
|
||||||
|
if (e->wd != wd || !(e->mask & IN_CLOSE)) {
|
||||||
|
r = -EIO;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
step = sizeof(struct inotify_event) + e->len;
|
||||||
|
assert(step <= (size_t) l);
|
||||||
|
|
||||||
|
e = (struct inotify_event*) ((uint8_t*) e + step);
|
||||||
|
l -= step;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
Loading…
Reference in New Issue
Block a user