Mercurial > dovecot > original-hg > dovecot-1.2
changeset 8066:28b1c4f68c9f HEAD
maildirlock: Do IPC with pipes instead of with signals. Fixes race conditions.
Based on patch by Kyle Wheeler.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Mon, 04 Aug 2008 16:10:47 -0400 |
parents | c832be51c7ac |
children | 6319603ffa70 |
files | src/util/maildirlock.c |
diffstat | 1 files changed, 23 insertions(+), 11 deletions(-) [+] |
line wrap: on
line diff
--- a/src/util/maildirlock.c Mon Aug 04 15:49:40 2008 -0400 +++ b/src/util/maildirlock.c Mon Aug 04 16:10:47 2008 -0400 @@ -3,6 +3,7 @@ #include "lib.h" #include "lib-signals.h" #include "ioloop.h" +#include "write-full.h" #include "file-dotlock.h" #include "maildir-uidlist.h" @@ -22,11 +23,9 @@ }; static struct ioloop *ioloop; -static bool success = FALSE; -static void sig_die(int signo, void *context ATTR_UNUSED) +static void sig_die(int signo ATTR_UNUSED, void *context ATTR_UNUSED) { - success = signo == SIGTERM; io_loop_stop(ioloop); } @@ -46,6 +45,8 @@ struct dotlock *dotlock; unsigned int timeout; pid_t pid, parent_pid; + int fd[2], ret; + char c; if (argc != 3) { fprintf(stderr, "Usage: maildirlock <path> <timeout>\n" @@ -53,6 +54,10 @@ return 1; } parent_pid = getpid(); + if (pipe(fd) != 0) { + fprintf(stderr, "pipe() failed: %m"); + return 1; + } pid = fork(); if (pid == (pid_t)-1) { @@ -62,17 +67,23 @@ /* call lib_init() only after fork so that PID gets set correctly */ lib_init(); + lib_signals_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) + close(fd[1]); + ret = read(fd[0], &c, 1); + if (ret < 0) { + fprintf(stderr, "read(pipe) failed: %m"); return 1; + } + if (ret != 1) { + /* locking timed out */ + return 1; + } + printf("%s", dec2str(pid)); return 0; } @@ -85,9 +96,10 @@ if (maildir_lock(argv[1], timeout, &dotlock) <= 0) return 1; - /* locked - send a */ - if (kill(parent_pid, SIGTERM) < 0) - i_fatal("kill(parent, SIGTERM) failed: %m"); + /* locked - send a byte */ + if (write_full(fd[1], "", 1) < 0) + i_fatal("write(pipe) failed: %m"); + io_loop_run(ioloop); file_dotlock_delete(&dotlock);