/*
- * lock.c -- routines to lock/unlock files
- *
- * This code is Copyright (c) 2002, by the authors of nmh. See the
- * COPYRIGHT file in the root directory of the nmh distribution for
- * complete copyright information.
- */
-
-/* Modified by Ruud de Rooij to support Miquel van Smoorenburg's liblockfile
- *
- * Since liblockfile locking shares most of its code with dot locking, it
- * is enabled by defining both DOT_LOCKING and HAVE_LIBLOCKFILE.
- *
- * Ruud de Rooij <ruud@debian.org> Sun, 28 Mar 1999 15:34:03 +0200
- */
+** lock.c -- routines to lock/unlock files
+**
+** This code is Copyright (c) 2002, by the authors of nmh. See the
+** COPYRIGHT file in the root directory of the nmh distribution for
+** complete copyright information.
+*/
+
+/*
+** Modified by Ruud de Rooij to support Miquel van Smoorenburg's liblockfile
+**
+** Since liblockfile locking shares most of its code with dot locking, it
+** is enabled by defining both DOT_LOCKING and HAVE_LIBLOCKFILE.
+**
+** Ruud de Rooij <ruud@debian.org> Sun, 28 Mar 1999 15:34:03 +0200
+*/
#include <h/mh.h>
#include <h/signals.h>
# endif
#endif
-#ifdef HAVE_ERRNO_H
-# include <errno.h>
-#endif
+#include <errno.h>
#ifdef HAVE_FCNTL_H
# include <fcntl.h>
};
/*
- * Amount of time to wait before
- * updating ctime of lock file.
- */
+** Amount of time to wait before
+** updating ctime of lock file.
+*/
#define NSECS 20
#if !defined(HAVE_LIBLOCKFILE)
/*
- * How old does a lock file need to be
- * before we remove it.
- */
+** How old does a lock file need to be
+** before we remove it.
+*/
#define RSECS 180
#endif /* HAVE_LIBLOCKFILE */
#endif /* DOT_LOCKING */
/*
- * static prototypes
- */
+** static prototypes
+*/
#ifdef KERNEL_LOCKING
-static int lkopen_kernel (char *, int, mode_t);
+static int lkopen_kernel(char *, int, mode_t);
#endif
#ifdef DOT_LOCKING
-static int lkopen_dot (char *, int, mode_t);
-static void lockname (char *, struct lockinfo *, int);
-static void timerON (char *, int);
-static void timerOFF (int);
-static RETSIGTYPE alrmser (int);
-#endif
+static int lkopen_dot(char *, int, mode_t);
+static void lockname(char *, struct lockinfo *, int);
+static void timerON(char *, int);
+static void timerOFF(int);
+static RETSIGTYPE alrmser(int);
#if !defined(HAVE_LIBLOCKFILE)
-static int lockit (struct lockinfo *);
+static int lockit(struct lockinfo *);
+#endif
#endif
/*
- * Base routine to open and lock a file,
- * and return a file descriptor.
- */
+** Base routine to open and lock a file,
+** and return a file descriptor.
+*/
int
-lkopen (char *file, int access, mode_t mode)
+lkopen(char *file, int access, mode_t mode)
{
#ifdef KERNEL_LOCKING
return lkopen_kernel(file, access, mode);
/*
- * Base routine to close and unlock a file,
- * given a file descriptor.
- */
+** Base routine to close and unlock a file,
+** given a file descriptor.
+*/
int
-lkclose (int fd, char *file)
+lkclose(int fd, char *file)
{
#ifdef FCNTL_LOCKING
struct flock buf;
#endif
#ifdef FLOCK_LOCKING
- flock (fd, LOCK_UN);
+ flock(fd, LOCK_UN);
#endif
#ifdef LOCKF_LOCKING
/* make sure we unlock the whole thing */
- lseek (fd, (off_t) 0, SEEK_SET);
- lockf (fd, F_ULOCK, 0L);
+ lseek(fd, (off_t) 0, SEEK_SET);
+ lockf(fd, F_ULOCK, 0L);
#endif
#ifdef DOT_LOCKING
- lockname (file, &lkinfo, 0); /* get name of lock file */
+ lockname(file, &lkinfo, 0); /* get name of lock file */
#if !defined(HAVE_LIBLOCKFILE)
- unlink (lkinfo.curlock); /* remove lock file */
+ unlink(lkinfo.curlock); /* remove lock file */
#else
lockfile_remove(lkinfo.curlock);
#endif /* HAVE_LIBLOCKFILE */
- timerOFF (fd); /* turn off lock timer */
+ timerOFF(fd); /* turn off lock timer */
#endif /* DOT_LOCKING */
- return (close (fd));
+ return (close(fd));
}
/*
- * Base routine to open and lock a file,
- * and return a FILE pointer
- */
+** Base routine to open and lock a file,
+** and return a FILE pointer
+*/
FILE *
-lkfopen (char *file, char *mode)
+lkfopen(char *file, char *mode)
{
int fd, access;
FILE *fp;
- if (strcmp (mode, "r") == 0)
+ if (strcmp(mode, "r") == 0)
access = O_RDONLY;
- else if (strcmp (mode, "r+") == 0)
+ else if (strcmp(mode, "r+") == 0)
access = O_RDWR;
- else if (strcmp (mode, "w") == 0)
+ else if (strcmp(mode, "w") == 0)
access = O_WRONLY | O_CREAT | O_TRUNC;
- else if (strcmp (mode, "w+") == 0)
+ else if (strcmp(mode, "w+") == 0)
access = O_RDWR | O_CREAT | O_TRUNC;
- else if (strcmp (mode, "a") == 0)
+ else if (strcmp(mode, "a") == 0)
access = O_WRONLY | O_CREAT | O_APPEND;
- else if (strcmp (mode, "a+") == 0)
+ else if (strcmp(mode, "a+") == 0)
access = O_RDWR | O_CREAT | O_APPEND;
else {
errno = EINVAL;
return NULL;
}
- if ((fd = lkopen (file, access, 0666)) == -1)
+ if ((fd = lkopen(file, access, 0666)) == -1)
return NULL;
- if ((fp = fdopen (fd, mode)) == NULL) {
- close (fd);
+ if ((fp = fdopen(fd, mode)) == NULL) {
+ close(fd);
return NULL;
}
/*
- * Base routine to close and unlock a file,
- * given a FILE pointer
- */
+** Base routine to close and unlock a file,
+** given a FILE pointer
+*/
int
-lkfclose (FILE *fp, char *file)
+lkfclose(FILE *fp, char *file)
{
#ifdef FCNTL_LOCKING
struct flock buf;
#endif
#ifdef FLOCK_LOCKING
- flock (fileno(fp), LOCK_UN);
+ flock(fileno(fp), LOCK_UN);
#endif
#ifdef LOCKF_LOCKING
/* make sure we unlock the whole thing */
- fseek (fp, 0L, SEEK_SET);
- lockf (fileno(fp), F_ULOCK, 0L);
+ fseek(fp, 0L, SEEK_SET);
+ lockf(fileno(fp), F_ULOCK, 0L);
#endif
#ifdef DOT_LOCKING
- lockname (file, &lkinfo, 0); /* get name of lock file */
+ lockname(file, &lkinfo, 0); /* get name of lock file */
#if !defined(HAVE_LIBLOCKFILE)
- unlink (lkinfo.curlock); /* remove lock file */
+ unlink(lkinfo.curlock); /* remove lock file */
#else
lockfile_remove(lkinfo.curlock);
#endif /* HAVE_LIBLOCKFILE */
- timerOFF (fileno(fp)); /* turn off lock timer */
+ timerOFF(fileno(fp)); /* turn off lock timer */
#endif /* DOT_LOCKING */
- return (fclose (fp));
+ return (fclose(fp));
}
#ifdef KERNEL_LOCKING
/*
- * open and lock a file, using kernel locking
- */
+** open and lock a file, using kernel locking
+*/
static int
-lkopen_kernel (char *file, int access, mode_t mode)
+lkopen_kernel(char *file, int access, mode_t mode)
{
int fd, i, j;
access &= ~O_APPEND;
/*
- * We MUST have write permission or
- * lockf/fcntl() won't work
- */
+ ** We MUST have write permission or
+ ** lockf/fcntl() won't work
+ */
if ((access & 03) == O_RDONLY) {
access &= ~O_RDONLY;
access |= O_RDWR;
}
# endif /* LOCKF_LOCKING || FCNTL_LOCKING */
- if ((fd = open (file, access | O_NDELAY, mode)) == -1)
+ if ((fd = open(file, access | O_NDELAY, mode)) == -1)
return -1;
# ifdef FCNTL_LOCKING
buf.l_whence = SEEK_SET;
buf.l_start = 0;
buf.l_len = 0;
- if (fcntl (fd, F_SETLK, &buf) != -1)
+ if (fcntl(fd, F_SETLK, &buf) != -1)
return fd;
# endif
# ifdef FLOCK_LOCKING
- if (flock (fd, (((access & 03) == O_RDONLY) ? LOCK_SH :
+ if (flock(fd, (((access & 03) == O_RDONLY) ? LOCK_SH :
LOCK_EX) | LOCK_NB) != -1)
return fd;
# endif
# ifdef LOCKF_LOCKING
- if (lockf (fd, F_TLOCK, 0L) != -1) {
+ if (lockf(fd, F_TLOCK, 0L) != -1) {
/* see if we should be at the end */
if (j & O_APPEND)
- lseek (fd, (off_t) 0, SEEK_END);
+ lseek(fd, (off_t) 0, SEEK_END);
return fd;
}
# endif
j = errno;
- close (fd);
- sleep (5);
+ close(fd);
+ sleep(5);
}
- close (fd);
+ close(fd);
errno = j;
return -1;
}
#ifdef DOT_LOCKING
/*
- * open and lock a file, using dot locking
- */
+** open and lock a file, using dot locking
+*/
static int
-lkopen_dot (char *file, int access, mode_t mode)
+lkopen_dot(char *file, int access, mode_t mode)
{
int fd;
struct lockinfo lkinfo;
/* open the file */
- if ((fd = open (file, access, mode)) == -1)
+ if ((fd = open(file, access, mode)) == -1)
return -1;
/*
- * Get the name of the eventual lock file, as well
- * as a name for a temporary lock file.
- */
- lockname (file, &lkinfo, 1);
+ ** Get the name of the eventual lock file, as well
+ ** as a name for a temporary lock file.
+ */
+ lockname(file, &lkinfo, 1);
#if !defined(HAVE_LIBLOCKFILE)
{
int i;
for (i = 0;;) {
/* attempt to create lock file */
- if (lockit (&lkinfo) == 0) {
+ if (lockit(&lkinfo) == 0) {
/* if successful, turn on timer and return */
- timerON (lkinfo.curlock, fd);
+ timerON(lkinfo.curlock, fd);
return fd;
} else {
/*
- * Abort locking, if we fail to lock after 5 attempts
- * and are never able to stat the lock file.
- */
+ ** Abort locking, if we fail to lock after 5
+ ** attempts and are never able to stat the
+ ** lock file.
+ */
struct stat st;
- if (stat (lkinfo.curlock, &st) == -1) {
+ if (stat(lkinfo.curlock, &st) == -1) {
if (i++ > 5)
return -1;
- sleep (5);
+ sleep(5);
} else {
time_t curtime;
i = 0;
- time (&curtime);
+ time(&curtime);
- /* check for stale lockfile, else sleep */
+ /*
+ ** check for stale lockfile,
+ ** else sleep
+ */
if (curtime > st.st_ctime + RSECS)
- unlink (lkinfo.curlock);
+ unlink(lkinfo.curlock);
else
- sleep (5);
+ sleep(5);
}
- lockname (file, &lkinfo, 1);
+ lockname(file, &lkinfo, 1);
}
}
}
#if !defined(HAVE_LIBLOCKFILE)
/*
- * Routine that actually tries to create
- * the lock file.
- */
+** Routine that actually tries to create
+** the lock file.
+*/
static int
-lockit (struct lockinfo *li)
+lockit(struct lockinfo *li)
{
int fd;
char *curlock, *tmplock;
curlock = li->curlock;
tmplock = li->tmplock;
-#ifdef HAVE_MKSTEMP
if ((fd = mkstemp(tmplock)) == -1)
return -1;
-#else
- if (mktemp(tmplock) == NULL)
- return -1;
- if (unlink(tmplock) == -1 && errno != ENOENT)
- return -1;
- /* create the temporary lock file */
- if ((fd = creat(tmplock, 0600)) == -1)
- return -1;
-#endif
#if 0
/* write our process id into lock file */
- snprintf (buffer, sizeof(buffer), "nmh lock: pid %d\n", (int) getpid());
+ snprintf(buffer, sizeof(buffer), "nmh lock: pid %d\n", (int) getpid());
write(fd, buffer, strlen(buffer) + 1);
#endif
- close (fd);
+ close(fd);
/*
- * Now try to create the real lock file
- * by linking to the temporary file.
- */
+ ** Now try to create the real lock file
+ ** by linking to the temporary file.
+ */
fd = link(tmplock, curlock);
unlink(tmplock);
#endif /* HAVE_LIBLOCKFILE */
/*
- * Get name of lock file, and temporary lock file
- */
+** Get name of lock file, and temporary lock file
+*/
static void
-lockname (char *file, struct lockinfo *li, int isnewlock)
+lockname(char *file, struct lockinfo *li, int isnewlock)
{
int bplen, tmplen;
char *bp, *cp;
-#if 0
- struct stat st;
-#endif
-
- if ((cp = strrchr (file, '/')) == NULL || *++cp == 0)
+ if ((cp = strrchr(file, '/')) == NULL || *++cp == 0)
cp = file;
bp = li->curlock;
bplen = 0;
#ifdef LOCKDIR
- snprintf (bp, sizeof(li->curlock), "%s/", lockdir);
- tmplen = strlen (bp);
+ snprintf(bp, sizeof(li->curlock), "%s/", lockdir);
+ tmplen = strlen(bp);
bp += tmplen;
bplen += tmplen;
#else
if (cp != file) {
- snprintf (bp, sizeof(li->curlock), "%.*s", (int)(cp - file), file);
- tmplen = strlen (bp);
+ snprintf(bp, sizeof(li->curlock), "%.*s", (int)(cp - file), file);
+ tmplen = strlen(bp);
bp += tmplen;
bplen += tmplen;
}
#endif
-#if 0
- /*
- * mmdf style dot locking. Currently not supported.
- * If we start supporting mmdf style dot locking,
- * we will need to change the return value of lockname
- */
- if (stat (file, &st) == -1)
- return -1;
-
- snprintf (bp, sizeof(li->curlock) - bplen, "LCK%05d.%05d",
- st.st_dev, st.st_ino);
-#endif
-
- snprintf (bp, sizeof(li->curlock) - bplen, "%s.lock", cp);
+ snprintf(bp, sizeof(li->curlock) - bplen, "%s.lock", cp);
#if !defined(HAVE_LIBLOCKFILE)
/*
- * If this is for a new lock, create a name for
- * the temporary lock file for lockit()
- */
+ ** If this is for a new lock, create a name for
+ ** the temporary lock file for lockit()
+ */
if (isnewlock) {
- if ((cp = strrchr (li->curlock, '/')) == NULL || *++cp == 0)
- strncpy (li->tmplock, ",LCK.XXXXXX", sizeof(li->tmplock));
+ if ((cp = strrchr(li->curlock, '/')) == NULL || *++cp == 0)
+ strncpy(li->tmplock, ",LCK.XXXXXX", sizeof(li->tmplock));
else
- snprintf (li->tmplock, sizeof(li->tmplock), "%.*s,LCK.XXXXXX",
- (int)(cp - li->curlock), li->curlock);
+ snprintf(li->tmplock, sizeof(li->tmplock),
+ "%.*s,LCK.XXXXXX",
+ (int)(cp - li->curlock), li->curlock);
}
#endif
}
/*
- * Add new lockfile to the list of open lockfiles
- * and start the lock file timer.
- */
+** Add new lockfile to the list of open lockfiles
+** and start the lock file timer.
+*/
static void
-timerON (char *curlock, int fd)
+timerON(char *curlock, int fd)
{
struct lock *lp;
size_t len;
- lp = (struct lock *) mh_xmalloc (sizeof(*lp));
+ lp = (struct lock *) mh_xmalloc(sizeof(*lp));
len = strlen(curlock) + 1;
lp->l_fd = fd;
- lp->l_lock = mh_xmalloc (len);
- memcpy (lp->l_lock, curlock, len);
+ lp->l_lock = mh_xmalloc(len);
+ memcpy(lp->l_lock, curlock, len);
lp->l_next = l_top;
if (!l_top) {
/* perhaps SIGT{STP,TIN,TOU} ? */
- SIGNAL (SIGALRM, alrmser);
- alarm (NSECS);
+ SIGNAL(SIGALRM, alrmser);
+ alarm(NSECS);
}
l_top = lp;
/*
- * Search through the list of lockfiles for the
- * current lockfile, and remove it from the list.
- */
+** Search through the list of lockfiles for the
+** current lockfile, and remove it from the list.
+*/
static void
-timerOFF (int fd)
+timerOFF(int fd)
{
struct lock *pp, *lp;
else
pp->l_next = lp->l_next;
- free (lp->l_lock);
- free (lp);
+ free(lp->l_lock);
+ free(lp);
}
}
/* if there are locks left, restart timer */
if (l_top)
- alarm (NSECS);
+ alarm(NSECS);
}
/*
- * If timer goes off, we update the ctime of all open
- * lockfiles, so another command doesn't remove them.
- */
+** If timer goes off, we update the ctime of all open
+** lockfiles, so another command doesn't remove them.
+*/
static RETSIGTYPE
-alrmser (int sig)
+alrmser(int sig)
{
char *lockfile;
struct lock *lp;
#ifndef RELIABLE_SIGNALS
- SIGNAL (SIGALRM, alrmser);
+ SIGNAL(SIGALRM, alrmser);
#endif
/* update the ctime of all the lock files */
#if !defined(HAVE_LIBLOCKFILE)
{
int j;
- if (*lockfile && (j = creat (lockfile, 0600)) != -1)
- close (j);
+ if (*lockfile && (j = creat(lockfile, 0600)) != -1)
+ close(j);
}
#else
lockfile_touch(lockfile);
}
/* restart the alarm */
- alarm (NSECS);
+ alarm(NSECS);
}
#endif /* DOT_LOCKING */