Mercurial > dovecot > original-hg > dovecot-1.2
changeset 7982:140d9f439c0f HEAD
maildirlock: Previous implementation wasn't usable - redesigned.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Tue, 08 Jul 2008 21:46:35 +0530 |
parents | bb9d3aabcb61 |
children | ba581bed8cc7 |
files | src/util/maildirlock.c |
diffstat | 1 files changed, 39 insertions(+), 9 deletions(-) [+] |
line wrap: on
line diff
--- 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 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 @@ 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 @@ { struct dotlock *dotlock; unsigned int timeout; - - lib_init(); - ioloop = io_loop_create(); + pid_t pid, parent_pid; if (argc != 3) { - printf("Usage: maildirlock <path> <timeout>\n" - " - SIGTERM will release the lock.\n"); + 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 (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);