file-lock.c revision caa1546576e3b813afc4769bd028629fb1dd2615
/* Copyright (c) 2002-2015 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "istream.h"
#include "file-lock.h"
#include <time.h>
#ifdef HAVE_FLOCK
#endif
struct file_lock {
int fd;
char *path;
int lock_type;
enum file_lock_method lock_method;
};
{
else
return FALSE;
return TRUE;
}
{
switch (method) {
case FILE_LOCK_METHOD_FCNTL:
return "fcntl";
case FILE_LOCK_METHOD_FLOCK:
return "flock";
case FILE_LOCK_METHOD_DOTLOCK:
return "dotlock";
}
i_unreached();
}
enum file_lock_method lock_method,
{
}
enum file_lock_method lock_method,
{
}
static const char *
{
return "";
return t_strdup_printf(" (%s lock held by pid %ld)",
}
static const char *
{
/* do anything except Linux support this? don't bother trying it for
OSes we don't know about. */
#ifdef __linux__
static bool have_proc_locks = TRUE;
int fd;
if (!have_proc_locks)
return FALSE;
return "";
if (fd == -1) {
return "";
}
major:minor:inode region-start region-end */
continue;
"READ" : "WRITE";
pid = 0;
}
} T_END;
if (pid == 0) {
/* not found */
return "";
}
return " (BUG: lock is held by our own process)";
#else
return "";
#endif
}
int lock_type)
{
const char *ret;
if (lock_method == FILE_LOCK_METHOD_FCNTL) {
if (ret[0] != '\0')
return ret;
}
return file_lock_find_proc_locks(lock_fd);
}
{
/* if EINTR took at least timeout_secs-1 number of seconds,
assume it was the alarm. otherwise log EINTR failure.
(We most likely don't want to retry EINTR since a signal
means somebody wants us to stop blocking). */
}
enum file_lock_method lock_method,
unsigned int timeout_secs, const char **error_r)
{
const char *lock_type_str;
int ret;
if (timeout_secs != 0)
switch (lock_method) {
case FILE_LOCK_METHOD_FCNTL: {
#ifndef HAVE_FCNTL
"Can't lock file %s: fcntl() locks not supported", path);
return -1;
#else
if (timeout_secs != 0) alarm(0);
if (ret == 0)
break;
if (timeout_secs == 0 &&
/* locked by another process */
"fcntl(%s, %s, F_SETLK) locking failed: %m "
return 0;
}
"fcntl(%s, %s, F_SETLKW) locking failed: "
"Timed out after %u seconds%s",
return 0;
}
return -1;
#endif
}
case FILE_LOCK_METHOD_FLOCK: {
#ifndef HAVE_FLOCK
"Can't lock file %s: flock() not supported", path);
return -1;
#else
switch (lock_type) {
case F_RDLCK:
break;
case F_WRLCK:
break;
case F_UNLCK:
break;
}
if (timeout_secs != 0) alarm(0);
if (ret == 0)
break;
/* locked by another process */
"flock(%s, %s) failed: %m "
return 0;
}
"Timed out after %u seconds%s",
return 0;
}
return -1;
#endif
}
case FILE_LOCK_METHOD_DOTLOCK:
/* we shouldn't get here */
i_unreached();
}
return 1;
}
enum file_lock_method lock_method,
unsigned int timeout_secs,
{
const char *error;
int ret;
if (ret < 0)
return ret;
}
enum file_lock_method lock_method,
unsigned int timeout_secs,
{
int ret;
if (ret <= 0) {
return ret;
}
return 1;
}
{
const char *error;
}
{
const char *error;
/* this shouldn't happen */
}
}
{
}