From c8f0b97d0f16970afc0e96af0329cadc51314eed Mon Sep 17 00:00:00 2001 From: Joachim Nilsson Date: Mon, 26 Oct 2015 04:31:32 +0100 Subject: [PATCH] tty.c: Handle EINVAL and use recommended inotify event size. The TTY plugin might fail in read() with EINVAL if the inotify event buffer is too small. Fix: set the receive event buffer to the size recommended in inotify(7). Also add a handler for EINVAL to close and reinitialize the inotify descriptor so we do not accidentally overrun the CPU with any unhandled errors. Signed-off-by: Joachim Nilsson --- plugins/tty.c | 10 ++++++++-- tty.h | 3 ++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/plugins/tty.c b/plugins/tty.c index f456663e..e76f6b93 100644 --- a/plugins/tty.c +++ b/plugins/tty.c @@ -46,7 +46,10 @@ static plugin_t plugin = { static void setup(void) { - plugin.io.fd = inotify_init1(IN_NONBLOCK); + if (plugin.io.fd) + close(plugin.io.fd); + + plugin.io.fd = inotify_init1(IN_NONBLOCK | IN_CLOEXEC); if (-1 == plugin.io.fd || inotify_add_watch(plugin.io.fd, "/dev", IN_CREATE | IN_DELETE) < 0) _e("Failed starting TTY watcher: %s", strerror(errno)); } @@ -60,9 +63,12 @@ static void watcher(void *UNUSED(arg), int fd, int UNUSED(events)) while ((len = read(fd, buf, sizeof(buf)))) { if (-1 == len) { + if (errno == EINVAL) + setup(); if (errno == EINTR) continue; - break; + + break; /* Likely EAGAIN */ } snprintf(name, sizeof(name), "/dev/%s", notified->name); diff --git a/tty.h b/tty.h index 25e32648..be263ea5 100644 --- a/tty.h +++ b/tty.h @@ -25,9 +25,10 @@ #ifndef FINIT_TTY_H_ #define FINIT_TTY_H_ +#include #include "queue.h" /* BSD sys/queue.h API */ -#define EVENT_SIZE ((sizeof(struct inotify_event) + 20)) +#define EVENT_SIZE ((sizeof(struct inotify_event) + NAME_MAX + 1)) typedef struct { char *name;