file-dotlock.c revision 94f9cf3436f949d6450e8cda523979fc1b11f103
/* Copyright (C) 2003 Timo Sirainen */
#include "lib.h"
#include "hostpid.h"
#include "write-full.h"
#include "file-dotlock.h"
#include <stdlib.h>
#include <signal.h>
#include <time.h>
/* 0.1 .. 0.2msec */
struct lock_info {
unsigned int stale_timeout;
};
{
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;
}
/* 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;
}
/* see if the file we're locking is being modified */
/* 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;
int fd;
if (fd == -1)
return -1;
/* got it, save the inode info */
return -1;
}
/* write our pid and host, if possible */
/* failed, leave it empty then */
return -1;
}
}
return -1;
}
return 1;
}
unsigned int timeout, unsigned int stale_timeout,
void *context),
{
const char *lock_path;
unsigned int stale_notify_threshold;
hostpid_init();
/* There's two ways to do this:
a) Rely on O_EXCL. Historically this hasn't always worked with NFS.
b) Create temp file and link() it to the file we want.
We now use a). It's easier to do and it never leaves temporary files
lying around. Also Postfix relies on it too, so I guess it's safe
enough nowadays.
*/
last_notify = 0;
do {
case -1:
return -1;
case 0:
unsigned int change_secs;
unsigned int wait_left;
last_notify = now;
if (change_secs >= stale_notify_threshold &&
change_secs <= wait_left) {
if (!callback(stale_timeout -
/* we don't want to override */
}
} else {
context);
}
}
break;
default:
if (checkonly ||
return 1;
return -1;
}
break;
}
} while (now < max_wait_time);
return 0;
}
{
const char *lock_path;
return 0;
}
return -1;
}
return 0;
}
return 0;
}
return -1;
}
return 1;
}