-
-/*
- * lock.c -- routines to lock/unlock files
+/* lock_file.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
#include <h/signals.h>
#include <h/utils.h>
#include <h/mts.h>
+#include "lock_file.h"
+#include "m_mktemp.h"
#ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
enum locktype { FCNTL_LOCKING, FLOCK_LOCKING, LOCKF_LOCKING, DOT_LOCKING };
-/*
- * Flags to indicate whether we've initialized the lock types, and
- * our saved lock types
- */
-static int datalockinit = 0;
-static int spoollockinit = 0;
+/* Our saved lock types. */
static enum locktype datalocktype, spoollocktype;
-
/* top of list containing all open locks */
static struct lock *l_top = NULL;
static int lkopen_flock (const char *, int, mode_t, int *);
#endif /* HAVE_FLOCK */
-static enum locktype init_locktype(const char *);
+static enum locktype init_locktype(const char *) PURE;
static int lkopen_dot (const char *, int, mode_t, int *);
static void lkclose_dot (int, const char *);
int
lkopendata(const char *file, int access, mode_t mode, int *failed_to_lock)
{
- if (! datalockinit) {
- char *cp = context_find("datalocking");
+ static bool deja_vu;
+
+ if (!deja_vu) {
+ char *dl;
- if (cp) {
- datalocktype = init_locktype(cp);
+ deja_vu = true;
+ if ((dl = context_find("datalocking"))) {
+ datalocktype = init_locktype(dl);
} else {
/* We default to fcntl locking for data files */
datalocktype = FCNTL_LOCKING;
}
-
- datalockinit = 1;
}
return lkopen(file, access, mode, datalocktype, failed_to_lock);
int lkopenspool(const char *file, int access, mode_t mode, int *failed_to_lock)
{
- if (! spoollockinit) {
- spoollocktype = init_locktype(spoollocking);
+ static bool deja_vu;
- spoollockinit = 1;
+ if (!deja_vu) {
+ deja_vu = true;
+ spoollocktype = init_locktype(spoollocking);
}
return lkopen(file, access, mode, spoollocktype, failed_to_lock);
{
if (strcmp (mode, "r") == 0)
return O_RDONLY;
- else if (strcmp (mode, "r+") == 0)
+ if (strcmp (mode, "r+") == 0)
return O_RDWR;
- else if (strcmp (mode, "w") == 0)
+ if (strcmp (mode, "w") == 0)
return O_WRONLY | O_CREAT | O_TRUNC;
- else if (strcmp (mode, "w+") == 0)
+ if (strcmp (mode, "w+") == 0)
return O_RDWR | O_CREAT | O_TRUNC;
- else if (strcmp (mode, "a") == 0)
+ if (strcmp (mode, "a") == 0)
return O_WRONLY | O_CREAT | O_APPEND;
- else if (strcmp (mode, "a+") == 0)
+ if (strcmp (mode, "a+") == 0)
return O_RDWR | O_CREAT | O_APPEND;
- else {
- errno = EINVAL;
- return -1;
- }
+
+ errno = EINVAL;
+ return -1;
}
/*
{
int i;
for (i = 0; i < LOCK_RETRIES; ++i) {
+ struct stat st;
+
/* attempt to create lock file */
if (lockit (&lkinfo) == 0) {
/* if successful, turn on timer and return */
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. Or, if
- * we can stat the lockfile but exceed LOCK_RETRIES
- * seconds waiting for it (by falling out of the loop).
- */
- struct stat st;
- if (stat (lkinfo.curlock, &st) == -1) {
- if (i++ > 5) break;
- sleep (1);
- } else {
- time_t curtime;
- time (&curtime);
-
- /* check for stale lockfile, else sleep */
- if (curtime > st.st_ctime + RSECS)
- (void) m_unlink (lkinfo.curlock);
- else
- sleep (1);
- }
- lockname (file, &lkinfo, 1);
}
+
+ /*
+ * Abort locking, if we fail to lock after 5 attempts
+ * and are never able to stat the lock file. Or, if
+ * we can stat the lockfile but exceed LOCK_RETRIES
+ * seconds waiting for it (by falling out of the loop).
+ */
+ if (stat (lkinfo.curlock, &st) == -1) {
+ if (i++ > 5) break;
+ sleep (1);
+ } else {
+ time_t curtime;
+ time (&curtime);
+
+ /* check for stale lockfile, else sleep */
+ if (curtime > st.st_ctime + RSECS)
+ (void) m_unlink (lkinfo.curlock);
+ else
+ sleep (1);
+ }
+ lockname (file, &lkinfo, 1);
}
+ close(fd);
*failed_to_lock = 1;
return -1;
}
timerON(lkinfo.curlock, fd);
return fd;
}
- else {
- close(fd);
- *failed_to_lock = 1;
- return -1;
- }
+
+ close(fd);
+ *failed_to_lock = 1;
+ return -1;
#endif /* HAVE_LIBLOCKFILE */
}
curlock = li->curlock;
if ((tmpfile = m_mktemp(li->tmplock, &fd, NULL)) == NULL) {
- advise(NULL, "unable to create temporary file in %s", li->tmplock);
+ inform("unable to create temporary file in %s", li->tmplock);
return -1;
}
fd = link(tmpfile, curlock);
(void) m_unlink(tmpfile);
- return (fd == -1 ? -1 : 0);
+ return fd == -1 ? -1 : 0;
}
#endif /* HAVE_LIBLOCKFILE */
snprintf (bp, sizeof(li->curlock) - bplen, "%s.lock", cp);
-#if !defined(HAVE_LIBLOCKFILE)
+#if defined(HAVE_LIBLOCKFILE)
+ NMH_UNUSED(isnewlock);
+#else
/*
* If this is for a new lock, create a name for
* the temporary lock file for lockit()
timerON (char *curlock, int fd)
{
struct lock *lp;
- size_t len;
NEW(lp);
-
- len = strlen(curlock) + 1;
+ lp->l_lock = mh_xstrdup(curlock);
lp->l_fd = fd;
- lp->l_lock = mh_xmalloc (len);
- memcpy (lp->l_lock, curlock, len);
lp->l_next = l_top;
if (!l_top) {
SIGNAL (SIGALRM, alrmser);
alarm (NSECS);
}
-
l_top = lp;
}
{
if (strcasecmp(lockname, "fcntl") == 0) {
return FCNTL_LOCKING;
- } else if (strcasecmp(lockname, "lockf") == 0) {
+ }
+ if (strcasecmp(lockname, "lockf") == 0) {
#ifdef HAVE_LOCKF
return LOCKF_LOCKING;
#else /* ! HAVE_LOCKF */
adios(NULL, "lockf not supported on this system");
#endif /* HAVE_LOCKF */
- } else if (strcasecmp(lockname, "flock") == 0) {
+ }
+ if (strcasecmp(lockname, "flock") == 0) {
#ifdef HAVE_FLOCK
return FLOCK_LOCKING;
#else /* ! HAVE_FLOCK */
adios(NULL, "flock not supported on this system");
#endif /* HAVE_FLOCK */
- } else if (strcasecmp(lockname, "dot") == 0) {
+ }
+ if (strcasecmp(lockname, "dot") == 0) {
return DOT_LOCKING;
- } else {
- adios(NULL, "Unknown lock type: \"%s\"", lockname);
- /* NOTREACHED */
- return 0;
}
+ adios(NULL, "Unknown lock type: \"%s\"", lockname);
+ /* NOTREACHED */
+ return 0;
}