X-Git-Url: https://diplodocus.org/git/nmh/blobdiff_plain/a4f7db8d70e4a1f285fb8345d3c9173b4a0cbe17..8374c3c:/sbr/lock_file.c?ds=inline diff --git a/sbr/lock_file.c b/sbr/lock_file.c index 3e322ba5..264e4695 100644 --- a/sbr/lock_file.c +++ b/sbr/lock_file.c @@ -85,20 +85,20 @@ static enum locktype datalocktype, spoollocktype; /* top of list containing all open locks */ static struct lock *l_top = NULL; -static int lkopen(const char *, int, mode_t, enum locktype); +static int lkopen(const char *, int, mode_t, enum locktype, int *); static int str2accbits(const char *); -static int lkopen_fcntl (const char *, int, mode_t); +static int lkopen_fcntl (const char *, int, mode_t, int *); #ifdef HAVE_LOCKF -static int lkopen_lockf (const char *, int, mode_t); +static int lkopen_lockf (const char *, int, mode_t, int *); #endif /* HAVE_LOCKF */ #ifdef HAVE_FLOCK -static int lkopen_flock (const char *, int, mode_t); +static int lkopen_flock (const char *, int, mode_t, int *); #endif /* HAVE_FLOCK */ static enum locktype init_locktype(const char *); -static int lkopen_dot (const char *, int, mode_t); +static int lkopen_dot (const char *, int, mode_t, int *); static void lkclose_dot (int, const char *); static void lockname (const char *, struct lockinfo *, int); static void timerON (char *, int); @@ -115,7 +115,7 @@ static int lockit (struct lockinfo *); */ int -lkopendata(const char *file, int access, mode_t mode) +lkopendata(const char *file, int access, mode_t mode, int *failed_to_lock) { if (! datalockinit) { char *cp = context_find("datalocking"); @@ -130,7 +130,7 @@ lkopendata(const char *file, int access, mode_t mode) datalockinit = 1; } - return lkopen(file, access, mode, datalocktype); + return lkopen(file, access, mode, datalocktype, failed_to_lock); } @@ -138,7 +138,7 @@ lkopendata(const char *file, int access, mode_t mode) * Locking using the spool locking algorithm */ -int lkopenspool(const char *file, int access, mode_t mode) +int lkopenspool(const char *file, int access, mode_t mode, int *failed_to_lock) { if (! spoollockinit) { spoollocktype = init_locktype(spoollocking); @@ -146,7 +146,7 @@ int lkopenspool(const char *file, int access, mode_t mode) spoollockinit = 1; } - return lkopen(file, access, mode, spoollocktype); + return lkopen(file, access, mode, spoollocktype, failed_to_lock); } @@ -155,7 +155,7 @@ int lkopenspool(const char *file, int access, mode_t mode) */ FILE * -lkfopendata(const char *file, const char *mode) +lkfopendata(const char *file, const char *mode, int *failed_to_lock) { FILE *fp; int oflags = str2accbits(mode); @@ -166,7 +166,7 @@ lkfopendata(const char *file, const char *mode) return NULL; } - if ((fd = lkopendata(file, oflags, 0666)) == -1) + if ((fd = lkopendata(file, oflags, 0666, failed_to_lock)) == -1) return NULL; if ((fp = fdopen (fd, mode)) == NULL) { @@ -182,6 +182,7 @@ lkfopenspool(const char *file, const char *mode) { FILE *fp; int oflags = str2accbits(mode); + int failed_to_lock = 0; int fd; if (oflags == -1) { @@ -189,7 +190,7 @@ lkfopenspool(const char *file, const char *mode) return NULL; } - if ((fd = lkopenspool(file, oflags, 0666)) == -1) + if ((fd = lkopenspool(file, oflags, 0666, &failed_to_lock)) == -1) return NULL; if ((fp = fdopen (fd, mode)) == NULL) { @@ -296,24 +297,25 @@ str2accbits(const char *mode) */ static int -lkopen (const char *file, int access, mode_t mode, enum locktype ltype) +lkopen (const char *file, int access, mode_t mode, enum locktype ltype, + int *failed_to_lock) { switch (ltype) { case FCNTL_LOCKING: - return lkopen_fcntl(file, access, mode); + return lkopen_fcntl(file, access, mode, failed_to_lock); case DOT_LOCKING: - return lkopen_dot(file, access, mode); + return lkopen_dot(file, access, mode, failed_to_lock); #ifdef HAVE_FLOCK case FLOCK_LOCKING: - return lkopen_flock(file, access, mode); + return lkopen_flock(file, access, mode, failed_to_lock); #endif /* HAVE_FLOCK */ #ifdef HAVE_LOCKF case LOCKF_LOCKING: - return lkopen_lockf(file, access, mode); + return lkopen_lockf(file, access, mode, failed_to_lock); #endif /* HAVE_FLOCK */ default: @@ -348,7 +350,7 @@ lkclose_dot (int fd, const char *file) */ static int -lkopen_fcntl(const char *file, int access, mode_t mode) +lkopen_fcntl(const char *file, int access, mode_t mode, int *failed_to_lock) { int fd, i, saved_errno; struct flock flk; @@ -375,6 +377,7 @@ lkopen_fcntl(const char *file, int access, mode_t mode) sleep(1); } + *failed_to_lock = 1; errno = saved_errno; return -1; } @@ -386,7 +389,7 @@ lkopen_fcntl(const char *file, int access, mode_t mode) */ static int -lkopen_flock(const char *file, int access, mode_t mode) +lkopen_flock(const char *file, int access, mode_t mode, int *failed_to_lock) { int fd, i, saved_errno, locktype; @@ -410,6 +413,7 @@ lkopen_flock(const char *file, int access, mode_t mode) sleep(1); } + *failed_to_lock = 1; errno = saved_errno; return -1; } @@ -420,7 +424,7 @@ lkopen_flock(const char *file, int access, mode_t mode) */ static int -lkopen_lockf(const char *file, int access, mode_t mode) +lkopen_lockf(const char *file, int access, mode_t mode, int *failed_to_lock) { int fd, i, saved_errno, saved_access; @@ -462,6 +466,7 @@ lkopen_lockf(const char *file, int access, mode_t mode) sleep(1); } + *failed_to_lock = 1; errno = saved_errno; return -1; } @@ -472,7 +477,7 @@ lkopen_lockf(const char *file, int access, mode_t mode) */ static int -lkopen_dot (const char *file, int access, mode_t mode) +lkopen_dot (const char *file, int access, mode_t mode, int *failed_to_lock) { int fd; struct lockinfo lkinfo; @@ -490,7 +495,7 @@ lkopen_dot (const char *file, int access, mode_t mode) #if !defined(HAVE_LIBLOCKFILE) { int i; - for (i = 0;;) { + for (i = 0; i < LOCK_RETRIES; ++i) { /* attempt to create lock file */ if (lockit (&lkinfo) == 0) { /* if successful, turn on timer and return */ @@ -499,27 +504,30 @@ lkopen_dot (const char *file, int access, mode_t mode) } else { /* * Abort locking, if we fail to lock after 5 attempts - * and are never able to stat the lock file. + * 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) - return -1; - sleep (5); + if (i++ > 5) break; + sleep (1); } else { time_t curtime; - i = 0; time (&curtime); /* check for stale lockfile, else sleep */ if (curtime > st.st_ctime + RSECS) (void) m_unlink (lkinfo.curlock); else - sleep (5); + sleep (1); } lockname (file, &lkinfo, 1); } } + + *failed_to_lock = 1; + return -1; } #else if (lockfile_create(lkinfo.curlock, 5, 0) == L_SUCCESS) { @@ -528,6 +536,7 @@ lkopen_dot (const char *file, int access, mode_t mode) } else { close(fd); + *failed_to_lock = 1; return -1; } #endif /* HAVE_LIBLOCKFILE */ @@ -552,7 +561,7 @@ lockit (struct lockinfo *li) curlock = li->curlock; if ((tmpfile = m_mktemp(li->tmplock, &fd, NULL)) == NULL) { - advise(NULL, "unable to create temporary file in %s", get_temp_dir()); + advise(NULL, "unable to create temporary file in %s", li->tmplock); return -1; } @@ -649,14 +658,10 @@ static void timerON (char *curlock, int fd) { struct lock *lp; - size_t len; - lp = (struct lock *) mh_xmalloc (sizeof(*lp)); - - len = strlen(curlock) + 1; + NEW(lp); + 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) { @@ -664,7 +669,6 @@ timerON (char *curlock, int fd) SIGNAL (SIGALRM, alrmser); alarm (NSECS); } - l_top = lp; }