changeset 3485:b3e135c37f06 HEAD

If dnotify/inotify isn't in kernel, handle the errors silently and without leaking.
author Timo Sirainen <tss@iki.fi>
date Tue, 12 Jul 2005 18:53:55 +0300
parents 5f23ce0fee04
children a511aa565020
files src/lib/ioloop-notify-dn.c src/lib/ioloop-notify-inotify.c
diffstat 2 files changed, 29 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib/ioloop-notify-dn.c	Tue Jul 12 18:48:51 2005 +0300
+++ b/src/lib/ioloop-notify-dn.c	Tue Jul 12 18:53:55 2005 +0300
@@ -16,6 +16,7 @@
 
 struct ioloop_notify_handler_context {
 	struct io *event_io;
+	int disabled;
 };
 
 static int event_pipe[2] = { -1, -1 };
@@ -67,12 +68,12 @@
 	if ((condition & IO_FILE_NOTIFY) != 0)
 		return NULL;
 
-	if (ctx->event_io == NULL) {
-		ctx->event_io =
-			io_add(event_pipe[0], IO_READ, event_callback, ioloop);
-	}
-
 	if (fcntl(fd, F_SETSIG, SIGRTMIN) < 0) {
+		if (errno == EINVAL) {
+			/* dnotify not in kernel. disable it. */
+			ctx->disabled = TRUE;
+			return NULL;
+		}
 		i_error("fcntl(F_SETSIG) failed: %m");
 		return FALSE;
 	}
@@ -83,6 +84,11 @@
 		return FALSE;
 	}
 
+	if (ctx->event_io == NULL) {
+		ctx->event_io =
+			io_add(event_pipe[0], IO_READ, event_callback, ioloop);
+	}
+
 	io = p_new(ioloop->pool, struct io, 1);
 	io->fd = fd;
         io->condition = condition;
@@ -101,6 +107,9 @@
 		ioloop->notify_handler_context;
 	struct io **io_p;
 
+	if (ctx->disabled)
+		return;
+
 	for (io_p = &ioloop->notifys; *io_p != NULL; io_p = &(*io_p)->next) {
 		if (*io_p == io) {
 			*io_p = io->next;
--- a/src/lib/ioloop-notify-inotify.c	Tue Jul 12 18:48:51 2005 +0300
+++ b/src/lib/ioloop-notify-inotify.c	Tue Jul 12 18:53:55 2005 +0300
@@ -94,17 +94,13 @@
 		ioloop->notify_handler_context;
 	struct io *io;
 	struct inotify_watch_request req;
-	int added = FALSE;
 	int watchdescriptor;
 
 	if ((condition & IO_FILE_NOTIFY) != 0)
 		return NULL;
 
-	if (ctx->event_io == NULL) {
-		added = TRUE;
-		ctx->event_io = io_add(ctx->inotify_fd, IO_READ,
-				       event_callback, ioloop);
-	}
+	if (ctx->disabled)
+		return NULL;
 
 	/* now set up the notification request and shoot it off */
 	req.fd = fd;
@@ -112,14 +108,16 @@
 	watchdescriptor = ioctl(ctx->inotify_fd, INOTIFY_WATCH, &req);
 	
 	if (watchdescriptor < 0) {
+		ctx->disabled = TRUE;
 		i_error("ioctl(INOTIFY_WATCH) failed: %m");
-		if (added) {
-			io_remove(ctx->event_io);
-			ctx->event_io = NULL;
-		}
 		return NULL;
 	}
 
+	if (ctx->event_io == NULL) {
+		ctx->event_io = io_add(ctx->inotify_fd, IO_READ,
+				       event_callback, ioloop);
+	}
+
 	io = p_new(ioloop->pool, struct io, 1);
 	io->fd = fd;
 	io->condition = condition;
@@ -139,6 +137,9 @@
 		ioloop->notify_handler_context;
 	struct io **io_p;
 
+	if (ctx->disabled)
+		return;
+
 	for (io_p = &ioloop->notifys; *io_p != NULL; io_p = &(*io_p)->next) {
 		if (*io_p == io) {
 			*io_p = io->next;
@@ -165,8 +166,10 @@
 		i_new(struct ioloop_notify_handler_context, 1);
 
 	ctx->inotify_fd = open("/dev/inotify", O_RDONLY);
-	if (ctx->inotify_fd < 0)
-		i_fatal("open(/dev/inotify) failed: %m");
+	if (ctx->inotify_fd < 0) {
+		ctx->disabled = TRUE;
+		return;
+	}
 
 	ctx->buf = buffer_create_dynamic(default_pool, INITIAL_INOTIFY_BUFLEN);
 }