mirror of
https://github.com/systemd/systemd.git
synced 2024-12-22 17:35:35 +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
|
||||
|
||||
* properly handle multiple inotify events per read() in path.c and util.c
|
||||
|
||||
* readahead: btrfs/LVM SSD detection
|
||||
|
||||
* 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);
|
||||
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);
|
||||
|
||||
|
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);
|
||||
|
||||
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;
|
||||
|
||||
r = -errno;
|
||||
} else
|
||||
r = -EIO;
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
|
||||
r = -errno;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (e.wd != wd || !(e.mask & IN_CLOSE)) {
|
||||
r = -EIO;
|
||||
goto fail;
|
||||
e = (struct inotify_event*) inotify_buffer;
|
||||
|
||||
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;
|
||||
|
Loading…
Reference in New Issue
Block a user