mbox-lock.c revision a8767e3a8dd08bb782f05dacf2c8877f3cba644e
/* Copyright (C) 2002 Timo Sirainen */
#include "lib.h"
#include "mbox-index.h"
#include "mbox-lock.h"
#include "mail-index-util.h"
#include <time.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#ifdef HAVE_FLOCK
#endif
/* 0.1 .. 0.2msec */
/* lock methods to use in wanted order */
#define DEFAULT_LOCK_METHODS "dotlock fcntl flock"
/* lock timeout */
#define DEFAULT_LOCK_TIMEOUT 300
/* assume stale dotlock if mbox file hasn't changed for n seconds */
#define DEFAULT_DOTLOCK_CHANGE_TIMEOUT 30
static int lock_settings_initialized = FALSE;
static void mbox_init_lock_settings(void)
{
const char *str;
char *const *lock;
use_dotlock = TRUE;
else
}
}
#ifdef HAVE_FLOCK
{
if (lock_type == MAIL_LOCK_EXCLUSIVE)
else if (lock_type == MAIL_LOCK_SHARED)
else
last_notify = 0;
if (errno != EWOULDBLOCK) {
return FALSE;
}
"release of flock() lock for mbox file "
return FALSE;
}
last_notify = now;
max_wait_time - now,
}
}
return TRUE;
}
#endif
{
return FALSE;
}
"release of fcntl() lock for mbox file "
return FALSE;
}
max_wait_time - now,
}
}
return TRUE;
}
{
unsigned int secs_left;
int fd;
/* don't bother with the temp files as we'd just leave them lying
around. besides, postfix also relies on O_EXCL working so we
might as well. */
last_size = 0; last_mtime = 0;
do {
/* see if there's been any changes in mbox */
break;
}
last_change = now;
}
/* no changes for a while, assume stale lock */
break;
}
continue;
}
if (last_notify != now) {
last_notify = now;
} else {
max_wait_time - now,
}
}
continue;
}
if (checkonly) {
/* we only wanted to check that the .lock file
doesn't exist. This is racy of course, but I don't
think there's any better way to do it really.
problem comes only when someone uses only dotlock
locking, and we can't fix that without dotlocking
ourself (which we didn't want to do here) */
return TRUE;
}
if (fd != -1) {
/* got it */
"fstat()");
return FALSE;
}
"close()");
return FALSE;
}
return TRUE;
}
return FALSE;
}
} while (now < max_wait_time);
"dotlock %s", path);
return FALSE;
}
{
index->mbox_dotlock_ino = 0;
return TRUE; /* doesn't exist anymore, ignore */
return FALSE;
}
/* make sure it's still our dotlock */
"Warning: Our dotlock file %s was overridden", path);
return FALSE;
}
return TRUE;
}
{
if (use_fcntl_lock && fcntl_before_flock) {
return FALSE;
}
#ifdef HAVE_FLOCK
if (use_flock) {
return FALSE;
}
#endif
if (use_fcntl_lock && !fcntl_before_flock) {
return FALSE;
}
return TRUE;
}
{
/* index must be locked before mbox file, to avoid deadlocks */
return TRUE;
/* make .lock file first to protect overwriting the file */
lock_type == MAIL_LOCK_SHARED &&
return FALSE;
}
/* now we need to have the file itself locked. open it if needed. */
if (!mbox_file_open(index)) {
(void)mbox_unlock(index);
return FALSE;
}
}
(void)mbox_unlock(index);
return FALSE;
}
return TRUE;
}
{
int failed;
return TRUE;
#ifdef HAVE_FLOCK
#endif
if (use_fcntl_lock &&
}
if (index->mbox_dotlock_ino != 0) {
}
/* make sure we don't keep mmap() between locks - there could have
been changes to file size which would break things. or actually
it'd break only if file was shrinked+grown back to exact size,
but still possible :) */
return !failed;
}