file-dotlock.c revision d5960ce1c0adda5c9e259bc429123ebc29c60bae
/* Copyright (C) 2003 Timo Sirainen */
#include "lib.h"
#include "str.h"
#include "hex-binary.h"
#include "hostpid.h"
#include "randgen.h"
#include "write-full.h"
#include "file-dotlock.h"
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <time.h>
#define DEFAULT_LOCK_SUFFIX ".lock"
/* 0.1 .. 0.2msec */
struct lock_info {
unsigned int stale_timeout;
unsigned int immediate_stale_timeout;
int fd;
};
{
int fd;
if (fd == -1)
return -1; /* ignore the actual error */
/* read line */
if (ret <= 0)
return -1;
/* fix the string */
ret--;
/* it should contain pid:host */
return -1;
*host++ = '\0';
/* host must be ours */
return -1;
return -1;
}
{
return -1;
}
return 1;
}
if (lock_info->immediate_stale_timeout != 0 &&
/* old lock file */
return -1;
}
return 1;
}
if (lock_info->stale_timeout == 0) {
/* no change checking */
return 0;
}
/* either our first check or someone else got the lock file.
check if it contains a pid whose existence we can verify */
}
/* we've local PID. Check if it exists. */
return 0;
return 0;
/* doesn't exist - go ahead and delete */
return -1;
}
return 1;
}
/* file doesn't exist. treat it as if
it hasn't changed */
} else {
return -1;
}
}
}
/* no changes for a while, assume stale lock */
return -1;
}
return 1;
}
return 0;
}
{
char randbuf[8];
int fd;
for (;;) {
do {
return -1;
}
if (fd != -1)
return fd;
return -1;
}
}
}
{
const char *str, *p;
/* we'll need our temp file first. */
if (temp_prefix == NULL) {
}
if (p != NULL) {
}
return -1;
}
return 0;
i_error("link(%s, %s) failed: %m",
return -1;
}
/* non-fatal, continue */
}
return 1;
}
static int
unsigned int timeout, unsigned int stale_timeout,
unsigned int immediate_stale_timeout,
void *context),
void *context)
{
const char *lock_path;
unsigned int stale_notify_threshold;
unsigned int change_secs, wait_left;
do {
if (do_wait) {
}
if (ret < 0)
break;
if (ret == 1) {
if (checkonly)
break;
if (ret != 0)
break;
}
last_notify = now;
t_push();
if (change_secs >= stale_notify_threshold &&
change_secs <= wait_left) {
/* we don't want to override */
}
} else {
}
t_pop();
}
} while (now < max_wait_time);
}
if (ret == 0)
return ret;
}
unsigned int timeout, unsigned int stale_timeout,
unsigned int immediate_stale_timeout,
void *context),
{
return ret;
/* write our pid and host, if possible */
/* failed, leave it empty then */
return -1;
}
}
/* save the inode info after writing */
return -1;
}
return -1;
}
return 1;
}
{
const char *lock_path;
return 0;
}
return -1;
}
return 0;
}
i_warning("Our dotlock file %s was modified (%s vs %s), "
"assuming it wasn't overridden", lock_path,
}
return 0;
}
return -1;
}
return 1;
}
{
}
int file_dotlock_open(const char *path,
const char *temp_prefix, const char *lock_suffix,
unsigned int timeout, unsigned int stale_timeout,
unsigned int immediate_stale_timeout,
void *context),
void *context)
{
if (lock_suffix == NULL)
if (ret <= 0)
return -1;
return fd;
}
int fd, int verify_owner)
{
const char *lock_path;
int old_errno;
if (lock_suffix == NULL)
if (verify_owner) {
return -1;
}
}
return -1;
}
if (verify_owner) {
return -1;
}
i_warning("Our dotlock file %s was overridden",
return 0;
}
}
return -1;
}
return 1;
}
{
int old_errno;
if (lock_suffix == NULL)
i_error("fstat(%s) failed: %m",
return -1;
}
i_error("close(%s) failed: %m",
return -1;
}
}