dovecot-1.2: maildirlock: Previous implementation wasn't usable ...

dovecot at dovecot.org dovecot at dovecot.org
Tue Jul 8 19:16:44 EEST 2008


details:   http://hg.dovecot.org/dovecot-1.2/rev/140d9f439c0f
changeset: 7982:140d9f439c0f
user:      Timo Sirainen <tss at iki.fi>
date:      Tue Jul 08 21:46:35 2008 +0530
description:
maildirlock: Previous implementation wasn't usable - redesigned.

diffstat:

1 file changed, 38 insertions(+), 8 deletions(-)
src/util/maildirlock.c |   46 ++++++++++++++++++++++++++++++++++++++--------

diffs (89 lines):

diff -r bb9d3aabcb61 -r 140d9f439c0f src/util/maildirlock.c
--- a/src/util/maildirlock.c	Tue Jul 08 21:11:23 2008 +0530
+++ b/src/util/maildirlock.c	Tue Jul 08 21:46:35 2008 +0530
@@ -8,6 +8,7 @@
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <unistd.h>
 #include <signal.h>
 
 static struct dotlock_settings dotlock_settings = {
@@ -21,9 +22,11 @@ static struct dotlock_settings dotlock_s
 };
 
 static struct ioloop *ioloop;
+static bool success = FALSE;
 
-static void sig_die(int signo ATTR_UNUSED, void *context ATTR_UNUSED)
+static void sig_die(int signo, void *context ATTR_UNUSED)
 {
+	success = signo == SIGTERM;
 	io_loop_stop(ioloop);
 }
 
@@ -34,6 +37,7 @@ static int maildir_lock(const char *path
 	dotlock_settings.use_excl_lock = getenv("DOTLOCK_USE_EXCL") != NULL;
 	dotlock_settings.nfs_flush = getenv("MAIL_NFS_STORAGE") != NULL;
 
+	path = t_strconcat(path, "/" MAILDIR_UIDLIST_NAME, NULL);
 	return file_dotlock_create(&dotlock_settings, path, 0, dotlock_r);
 }
 
@@ -41,23 +45,49 @@ int main(int argc, const char *argv[])
 {
 	struct dotlock *dotlock;
 	unsigned int timeout;
+	pid_t pid, parent_pid;
 
+	if (argc != 3) {
+		fprintf(stderr, "Usage: maildirlock <path> <timeout>\n"
+			" - SIGTERM will release the lock.\n");
+		return 1;
+	}
+	parent_pid = getpid();
+
+	pid = fork();
+	if (pid == (pid_t)-1) {
+		fprintf(stderr, "fork() failed: %m");
+		return 1;
+	}
+
+	/* call lib_init() only after fork so that PID gets set correctly */
 	lib_init();
 	ioloop = io_loop_create();
+	lib_signals_init();
+	lib_signals_set_handler(SIGINT, TRUE, sig_die, NULL);
+	lib_signals_set_handler(SIGTERM, TRUE, sig_die, NULL);
+	lib_signals_set_handler(SIGCHLD, TRUE, sig_die, NULL);
 
-	if (argc != 3) {
-		printf("Usage: maildirlock <path> <timeout>\n"
-		       " - SIGTERM will release the lock.\n");
-		return 1;
+	if (pid != 0) {
+		/* master - wait for the child process to finish locking */
+		io_loop_run(ioloop);
+		if (!success)
+			return 1;
+		printf("%s", dec2str(pid));
+		return 0;
 	}
+
+	/* child process - stdout has to be closed so that caller knows when
+	   to stop reading it. */
+	dup2(STDERR_FILENO, STDOUT_FILENO);
 
 	timeout = strtoul(argv[2], NULL, 10);
 	if (maildir_lock(argv[1], timeout, &dotlock) <= 0)
 		return 1;
 
-	lib_signals_init();
-	lib_signals_set_handler(SIGINT, TRUE, sig_die, NULL);
-	lib_signals_set_handler(SIGTERM, TRUE, sig_die, NULL);
+	/* locked - send a  */
+	if (kill(parent_pid, SIGTERM) < 0)
+		i_fatal("kill(parent, SIGTERM) failed: %m");
 	io_loop_run(ioloop);
 
 	file_dotlock_delete(&dotlock);


More information about the dovecot-cvs mailing list