[dovecot-cvs] dovecot/src/lib ioloop-internal.h, 1.14, 1.15 ioloop-notify-dn.c, 1.6, 1.7 ioloop-notify-inotify.c, 1.4, 1.5 ioloop-notify-none.c, 1.3, 1.4 ioloop.c, 1.27, 1.28 ioloop.h, 1.11, 1.12

cras at dovecot.org cras at dovecot.org
Mon Aug 15 00:54:23 EEST 2005


Update of /var/lib/cvs/dovecot/src/lib
In directory talvi:/tmp/cvs-serv17029/lib

Modified Files:
	ioloop-internal.h ioloop-notify-dn.c ioloop-notify-inotify.c 
	ioloop-notify-none.c ioloop.c ioloop.h 
Log Message:
New inotify code and notify API change. Patch by Johannes Berg



Index: ioloop-internal.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib/ioloop-internal.h,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -d -r1.14 -r1.15
--- ioloop-internal.h	12 Jul 2005 15:44:49 -0000	1.14
+++ ioloop-internal.h	14 Aug 2005 21:54:20 -0000	1.15
@@ -61,8 +61,7 @@
 void io_loop_notify_handler_init(struct ioloop *ioloop);
 void io_loop_notify_handler_deinit(struct ioloop *ioloop);
 
-struct io *io_loop_notify_add(struct ioloop *ioloop, int fd,
-			      enum io_condition condition,
+struct io *io_loop_notify_add(struct ioloop *ioloop, const char *path,
 			      io_callback_t *callback, void *context);
 void io_loop_notify_remove(struct ioloop *ioloop, struct io *io);
 

Index: ioloop-notify-dn.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib/ioloop-notify-dn.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- ioloop-notify-dn.c	12 Jul 2005 21:15:16 -0000	1.6
+++ ioloop-notify-dn.c	14 Aug 2005 21:54:20 -0000	1.7
@@ -58,16 +58,19 @@
 	}
 }
 
-struct io *io_loop_notify_add(struct ioloop *ioloop, int fd,
-			      enum io_condition condition,
+struct io *io_loop_notify_add(struct ioloop *ioloop, const char *path,
 			      io_callback_t *callback, void *context)
 {
 	struct ioloop_notify_handler_context *ctx =
 		ioloop->notify_handler_context;
 	struct io *io;
+	int fd;
 
-	if ((condition & IO_FILE_NOTIFY) != 0)
+	fd = open(path, O_RDONLY);
+	if (fd == -1) {
+		i_error("open(%s) for dnotify failed: %m", path);
 		return NULL;
+	}
 
 	if (fcntl(fd, F_SETSIG, SIGRTMIN) < 0) {
 		if (errno == EINVAL) {
@@ -76,13 +79,17 @@
 			return NULL;
 		}
 		i_error("fcntl(F_SETSIG) failed: %m");
-		return FALSE;
+		return NULL;
 	}
 	if (fcntl(fd, F_NOTIFY, DN_CREATE | DN_DELETE | DN_RENAME |
 		  DN_MULTISHOT) < 0) {
-		i_error("fcntl(F_NOTIFY) failed: %m");
+		/* we fail here if we're trying to add dnotify to
+		   non-directory fd. fail silently in that case. */
+		if (errno != ENOTDIR)
+			i_error("fcntl(F_NOTIFY) failed: %m");
 		(void)fcntl(fd, F_SETSIG, 0);
-		return FALSE;
+		(void)close(fd);
+		return NULL;
 	}
 
 	if (ctx->event_io == NULL) {
@@ -92,7 +99,6 @@
 
 	io = p_new(ioloop->pool, struct io, 1);
 	io->fd = fd;
-        io->condition = condition;
 
 	io->callback = callback;
         io->context = context;
@@ -122,6 +128,8 @@
 		i_error("fcntl(F_NOTIFY, 0) failed: %m");
 	if (fcntl(io->fd, F_SETSIG, 0) < 0)
 		i_error("fcntl(F_SETSIG, 0) failed: %m");
+	if (close(io->fd))
+		i_error("close(dnotify) failed: %m");
 
 	p_free(ioloop->pool, io);
 

Index: ioloop-notify-inotify.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib/ioloop-notify-inotify.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- ioloop-notify-inotify.c	12 Jul 2005 21:15:16 -0000	1.4
+++ ioloop-notify-inotify.c	14 Aug 2005 21:54:20 -0000	1.5
@@ -5,6 +5,7 @@
 
 #ifdef IOLOOP_NOTIFY_INOTIFY
 
+#include "fd-close-on-exec.h"
 #include "ioloop-internal.h"
 #include "buffer.h"
 #include "network.h"
@@ -14,6 +15,7 @@
 #include <fcntl.h>
 #include <sys/ioctl.h>
 #include <linux/inotify.h>
+#include <linux/inotify-syscalls.h>
 
 #define INITIAL_INOTIFY_BUFLEN (FILENAME_MAX + sizeof(struct inotify_event))
 #define MAXIMAL_INOTIFY_BUFLEN (32*1024)
@@ -87,33 +89,26 @@
 	while (event_read_next(ioloop)) ;
 }
 
-struct io *io_loop_notify_add(struct ioloop *ioloop, int fd,
-			      enum io_condition condition,
+struct io *io_loop_notify_add(struct ioloop *ioloop, const char *path,
 			      io_callback_t *callback, void *context)
 {
 	struct ioloop_notify_handler_context *ctx =
 		ioloop->notify_handler_context;
 	struct io *io;
-	struct inotify_watch_request req;
 	int watchdescriptor;
 
-	if ((condition & IO_FILE_NOTIFY) != 0)
-		return NULL;
-
 	if (ctx->disabled)
 		return NULL;
 
-	/* now set up the notification request and shoot it off */
-	req.fd = fd;
-	req.mask = IN_CREATE | IN_DELETE | IN_MOVE | IN_CLOSE | IN_MODIFY;
-	watchdescriptor = ioctl(ctx->inotify_fd, INOTIFY_WATCH, &req);
+	watchdescriptor = inotify_add_watch(ctx->inotify_fd, path,
+					    IN_CREATE | IN_DELETE | IN_MOVE |
+					    IN_CLOSE | IN_MODIFY);
 	
 	if (watchdescriptor < 0) {
 		ctx->disabled = TRUE;
-		i_error("ioctl(INOTIFY_WATCH) failed: %m");
+		i_error("inotify_add_watch(%s) failed: %m", path);
 		return NULL;
 	}
-	fd_close_on_exec(watchdescriptor, TRUE);
 
 	if (ctx->event_io == NULL) {
 		ctx->event_io = io_add(ctx->inotify_fd, IO_READ,
@@ -121,8 +116,7 @@
 	}
 
 	io = p_new(ioloop->pool, struct io, 1);
-	io->fd = fd;
-	io->condition = condition;
+	io->fd = -1;
 
 	io->callback = callback;
 	io->context = context;
@@ -149,8 +143,8 @@
 		}
 	}
 
-	if (ioctl(ctx->inotify_fd, INOTIFY_IGNORE, &io->notify_context) < 0)
-		i_error("ioctl(INOTIFY_IGNORE) failed: %m");
+	if (inotify_rm_watch(ctx->inotify_fd, io->notify_context) < 0)
+		i_error("inotify_rm_watch() failed: %m");
 
 	p_free(ioloop->pool, io);
 
@@ -167,8 +161,9 @@
 	ctx = ioloop->notify_handler_context =
 		i_new(struct ioloop_notify_handler_context, 1);
 
-	ctx->inotify_fd = open("/dev/inotify", O_RDONLY);
-	if (ctx->inotify_fd < 0) {
+	ctx->inotify_fd = inotify_init();
+	if (ctx->inotify_fd == -1) {
+		i_error("inotify_init() failed: %m");
 		ctx->disabled = TRUE;
 		return;
 	}
@@ -182,10 +177,12 @@
 	struct ioloop_notify_handler_context *ctx =
 		ioloop->notify_handler_context;
 
-	if (close(ctx->inotify_fd) < 0)
-		i_error("close(/dev/inotify) failed: %m");
+	if (ctx->inotify_fd != -1)
+		if (close(ctx->inotify_fd) < 0)
+			i_error("close(inotify descriptor) failed: %m");
 
-	buffer_free(ctx->buf);
+	if (ctx->buf != NULL)
+		buffer_free(ctx->buf);
 	i_free(ctx);
 }
 

Index: ioloop-notify-none.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib/ioloop-notify-none.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- ioloop-notify-none.c	12 Jul 2005 15:40:33 -0000	1.3
+++ ioloop-notify-none.c	14 Aug 2005 21:54:20 -0000	1.4
@@ -6,8 +6,7 @@
 #ifdef IOLOOP_NOTIFY_NONE
 
 struct io *io_loop_notify_add(struct ioloop *ioloop __attr_unused__,
-			      int fd __attr_unused__,
-			      enum io_condition condition __attr_unused__,
+			      const char *path __attr_unused__,
 			      io_callback_t *callback __attr_unused__,
 			      void *context __attr_unused__)
 {

Index: ioloop.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib/ioloop.c,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -d -r1.27 -r1.28
--- ioloop.c	14 Aug 2005 18:18:35 -0000	1.27
+++ ioloop.c	14 Aug 2005 21:54:20 -0000	1.28
@@ -22,11 +22,7 @@
 
 	i_assert(fd >= 0);
 	i_assert(callback != NULL);
-
-	if ((condition & IO_NOTIFY_MASK) != 0) {
-		return io_loop_notify_add(current_ioloop, fd, condition,
-					  callback, context);
-	}
+	i_assert((condition & IO_NOTIFY) == 0);
 
 	io = p_new(current_ioloop->pool, struct io, 1);
 	io->fd = fd;
@@ -46,9 +42,23 @@
 	return io;
 }
 
+struct io *io_add_notify(const char *path, io_callback_t *callback,
+			 void *context)
+{
+	struct io *io;
+
+	i_assert(path != NULL);
+	i_assert(callback != NULL);
+	
+	io = io_loop_notify_add(current_ioloop, path, callback, context);
+	if (io != NULL)
+		io->condition |= IO_NOTIFY;
+	return io;
+}
+
 void io_remove(struct io *io)
 {
-	if ((io->condition & IO_NOTIFY_MASK) != 0) {
+	if ((io->condition & IO_NOTIFY) != 0) {
 		io_loop_notify_remove(current_ioloop, io);
 		return;
 	}

Index: ioloop.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib/ioloop.h,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -d -r1.11 -r1.12
--- ioloop.h	24 Aug 2003 12:43:53 -0000	1.11
+++ ioloop.h	14 Aug 2005 21:54:20 -0000	1.12
@@ -11,10 +11,9 @@
 enum io_condition {
 	IO_READ		= 0x01,
 	IO_WRITE	= 0x02,
-	IO_DIR_NOTIFY	= 0x04,
-	IO_FILE_NOTIFY	= 0x08,
-
-	IO_NOTIFY_MASK	= IO_DIR_NOTIFY | IO_FILE_NOTIFY
+	
+	/* internal */
+	IO_NOTIFY	= 0x04,
 };
 
 typedef void io_callback_t(void *context);
@@ -30,10 +29,11 @@
    but make sure you don't create multiple handlers of same type, it's not
    checked and removing one will stop the other from working as well.
 
-   If IO_DIR_NOTIFY or IO_FILE_NOTIFY isn't supported by operating system
-   directly, this function returns NULL. */
+ */
 struct io *io_add(int fd, enum io_condition condition,
 		  io_callback_t *callback, void *context);
+struct io *io_add_notify(const char *path, io_callback_t *callback,
+			 void *context);
 void io_remove(struct io *io);
 
 /* Timeout handlers */



More information about the dovecot-cvs mailing list