home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
pc.louisiana.edu/pub/unix/
/
Louisiana_UNIX.tar
/
Louisiana_UNIX
/
lockfile.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-09-18
|
4KB
|
193 lines
/*
* LOCKFILE
*
* Create files for locking purposes.
*
* Usage: lockfile [-nuv] [-t <timeout>] <file>
* -n Don't block indefinitely waiting for a locked file. Only
* tries the lock once.
* -u Unlock (remove) the lock file.
* -v Verbose.
* -t <timeout> If the lock file alredy exists and is older than
* <timeout> seconds, assume it is stale and remove it.
* The default timeout is 300 seconds.
*
* Exit code is 0 if the lock succeeds, -1 otherwise.
*
* Created 9/95 by Lane Robert (lar@usl.edu)
*/
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <sys/time.h>
#include <errno.h>
#define EXIT_ERROR -1
#define EXIT_OK 0
#define USAGE fprintf(stderr, "%s: Usage: \"%s [-nuv][-t <timeout>] <file>\"\n", me, me)
extern int optind;
extern char *optarg;
extern int errno;
extern char *sys_errlist[];
char *me;
main (int argc, char **argv)
{
int noblock, timeout, unlock, verbose, ch;
char *fname;
noblock = 0;
timeout = 300;
unlock = 0;
verbose = 0;
me = argv[0];
while ((ch = getopt(argc, argv, "nt:uv")) != -1) {
switch(ch) {
case 'n':
noblock = 1;
break;
case 't':
timeout = atoi(optarg);
if (timeout <= 0) {
fprintf(stderr, "%s: Invalid timeout value \"%s\"\n",
me, optarg);
exit(EXIT_ERROR);
}
break;
case 'u':
unlock = 1;
break;
case 'v':
verbose = 1;
break;
default:
USAGE;
exit(EXIT_ERROR);
}
}
if (optind >= argc) {
USAGE;
exit(EXIT_ERROR);
}
else fname = argv[optind];
/* UNLOCK */
if (unlock) {
if (unlink(fname) != 0) {
if (errno == ENOENT) {
if (verbose) {
fprintf(stderr,
"%s: Warning: Cannot remove %s: file does not exist\n",
me, fname);
}
}
else {
fprintf(stderr, "%s: Cannot remove %s: %s\n", me, fname,
sys_errlist[errno]);
exit(EXIT_ERROR);
}
}
else {
if (verbose)
fprintf(stderr, "%s: Lock file %s removed.\n", me,
fname);
}
}
else {
/* LOCK */
while (1) {
struct stat statbuf;
time_t now;
if (stat(fname, &statbuf) != 0) {
if (errno == ENOENT) {
int fd;
/* File doesn't exist; create it. */
if ((fd = open(fname, O_WRONLY|O_EXCL|O_CREAT, 0666))
< 0) {
if (errno == EEXIST) {
if (verbose)
fprintf(stderr,
"%s: Creation of %s failed.\n",
fname, me);
}
else {
fprintf(stderr,
"%s: Creation of %s failed: %s\n",
me, fname, sys_errlist[errno]);
exit(EXIT_ERROR);
}
if (noblock)
exit(EXIT_ERROR);
else {
if (verbose)
fprintf(stderr, "%s: Retrying.\n",
me);
sleep(15);
continue;
}
}
else {
if (verbose)
fprintf(stderr,
"%s: Lock file %s created.\n", me,
fname);
close(fd);
exit(EXIT_OK);
}
}
else {
fprintf(stderr, "%s: Cannot create %s: %s\n", me,
fname, sys_errlist[errno]);
exit(EXIT_ERROR);
}
}
/* Lock file exists. Is it stale? */
now = time((time_t *)NULL);
if (now - statbuf.st_mtime >= timeout) {
/* It's stale. Remove it. */
if (verbose)
fprintf(stderr,
"%s: Lock file %s is old. Removing it.\n",
me, fname);
if (unlink(fname) != 0 && errno != ENOENT) {
fprintf(stderr,
"%s: Cannot remove old file %s: %s\n", me,
fname, sys_errlist[errno]);
exit(EXIT_ERROR);
}
if (verbose)
fprintf(stderr, "%s: Retrying lock of %s.\n", me,
fname);
continue;
}
/*
* Lock file exists and is not stale.
* Unless we are in nonblock mode, sleep
* for a short time and retry.
*/
if (verbose)
fprintf(stderr,
"%s: Creation of lock file %s failed.\n",
me, fname);
if (noblock)
exit(EXIT_ERROR);
if (verbose)
fprintf(stderr, "%s: Retrying lock of %s.\n", me, fname);
sleep(15);
}
}
exit(EXIT_OK);
}