file-dotlock.c revision cfbe8dbf68fd1c2a98444cdfd0145e002965dd50
/* 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 dotlock {
struct dotlock_settings settings;
char *path;
int fd;
};
struct lock_info {
const struct dotlock_settings *set;
int fd;
int have_pid;
};
static struct dotlock *
{
return dotlock;
}
{
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;
}
/* old lock file */
return -1;
}
return 1;
}
/* either our first check or someone else got the lock file. */
/* no pid checking */
pid = -1;
} else {
/* we just checked the pid */
return 0;
}
/* re-read the pid. even if all times and inodes are the same,
the PID in the file might have changed if lock files were
rapidly being recreated. */
}
/* we've local PID. Check if it exists. */
return 0;
/* it's us. either we're locking it again, or it's a
stale lock file with same pid than us. either way,
recreate it.. */
}
/* doesn't exist - go ahead and delete */
return -1;
}
return 1;
}
if (stale_timeout == 0) {
/* no change checking */
return 0;
}
/* 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;
}
{
const char *str;
/* write our pid and host, if possible */
/* failed, leave it empty then */
return -1;
}
}
return 0;
}
static int
{
unsigned char randbuf[8];
int fd;
for (;;) {
do {
return -1;
}
if (fd != -1)
break;
return -1;
}
}
if (write_pid) {
return -1;
}
}
return fd;
}
{
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;
}
{
int fd;
if (fd == -1) {
return 0;
return -1;
}
if (write_pid) {
return -1;
}
}
return 1;
}
{
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 ((flags & DOTLOCK_CREATE_FLAG_CHECKONLY) != 0)
break;
if (ret != 0)
break;
}
last_notify = now;
t_push();
if (change_secs >= stale_notify_threshold &&
change_secs <= wait_left) {
unsigned int secs_left =
/* we don't want to override */
}
} else {
}
t_pop();
}
} while (now < max_wait_time);
if (ret > 0) {
ret = -1;
} else {
/* successful dotlock creation */
}
}
}
if (ret == 0)
return ret;
}
{
int old_errno;
}
}
enum dotlock_create_flags flags,
{
const char *lock_path;
return ret;
}
return -1;
}
/* some NFS implementations may have used cached mtime in previous
fstat() call. Check again to avoid "dotlock was modified" errors. */
return -1;
}
/* extra sanity check won't hurt.. */
i_error("dotlock %s was immediately recreated under us",
return -1;
}
return 1;
}
{
const char *lock_path;
i_warning("Our dotlock file %s was deleted "
"(kept it %d secs)", lock_path,
return 0;
}
return -1;
}
i_warning("Our dotlock file %s was overridden "
"(kept it %d secs)", lock_path,
return 0;
}
i_warning("Our dotlock file %s was modified (%s vs %s), "
"assuming it wasn't overridden (kept it %d secs)",
}
i_warning("Our dotlock file %s was deleted "
"(kept it %d secs)", lock_path,
return 0;
}
return -1;
}
return 1;
}
enum dotlock_create_flags flags,
{
int ret;
if (ret <= 0) {
return -1;
}
}
enum dotlock_replace_flags flags)
{
const char *lock_path;
int fd;
if ((flags & DOTLOCK_REPLACE_FLAG_DONT_CLOSE_FD) != 0)
if ((flags & DOTLOCK_REPLACE_FLAG_VERIFY_OWNER) != 0) {
return -1;
}
return -1;
}
i_warning("Our dotlock file %s was overridden "
"(kept it %u secs)", lock_path,
return 0;
}
}
return -1;
}
return 1;
}