X-Git-Url: http://git.marmaro.de/?p=mmh;a=blobdiff_plain;f=sbr%2Flock_file.c;h=7309c8681b849e76d73673af755461590b82fde4;hp=5bc83cc8d8869ae0f47513a21cc864ca1ed51a9d;hb=e48142e43bfeef1a44fb2f7131918b7172cd427e;hpb=a485ed478abbd599d8c9aab48934e7a26733ecb1 diff --git a/sbr/lock_file.c b/sbr/lock_file.c index 5bc83cc..7309c86 100644 --- a/sbr/lock_file.c +++ b/sbr/lock_file.c @@ -1,37 +1,32 @@ /* - * 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 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 Sun, 28 Mar 1999 15:34:03 +0200 +*/ + +#include #include #include #include +#include -#ifdef TIME_WITH_SYS_TIME +#ifdef HAVE_SYS_TIME_H # include -# include -#else -# ifdef TM_IN_SYS_TIME -# include -# else -# include -# endif #endif +#include -#ifdef HAVE_ERRNO_H -# include -#endif +#include #ifdef HAVE_FCNTL_H # include @@ -49,8 +44,10 @@ #include #endif -#ifdef LOCKDIR +#ifdef DOT_LOCKING +# ifdef LOCKDIR char *lockdir = LOCKDIR; +# endif #endif /* Are we using any kernel locking? */ @@ -69,16 +66,16 @@ struct lockinfo { }; /* - * 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 */ @@ -94,31 +91,31 @@ static struct lock *l_top = NULL; #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 void 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); @@ -131,12 +128,12 @@ lkopen (char *file, int access, mode_t 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; @@ -158,62 +155,62 @@ lkclose (int fd, char *file) #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; } @@ -222,12 +219,12 @@ lkfopen (char *file, char *mode) /* - * 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; @@ -249,37 +246,37 @@ lkfclose (FILE *fp, char *file) #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; @@ -297,16 +294,16 @@ lkopen_kernel (char *file, int access, mode_t mode) 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 @@ -314,31 +311,31 @@ lkopen_kernel (char *file, int access, mode_t mode) 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(1); } - close (fd); + close(fd); errno = j; return -1; } @@ -349,56 +346,60 @@ lkopen_kernel (char *file, int access, mode_t mode) #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(1); } 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(1); } - lockname (file, &lkinfo, 1); + lockname(file, &lkinfo, 1); } } } @@ -415,12 +416,12 @@ lkopen_dot (char *file, int access, mode_t mode) #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; @@ -432,31 +433,23 @@ lockit (struct lockinfo *li) 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) + if ((fd = mkstemp(tmplock)) == -1) { + advise(NULL, "unable to create temporary file in %s", tmplock); 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); @@ -465,92 +458,76 @@ lockit (struct lockinfo *li) #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; @@ -558,12 +535,12 @@ timerON (char *curlock, int fd) /* - * 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; @@ -580,40 +557,36 @@ timerOFF (int fd) 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) +static void +alrmser(int sig) { char *lockfile; struct lock *lp; -#ifndef RELIABLE_SIGNALS - SIGNAL (SIGALRM, alrmser); -#endif - /* update the ctime of all the lock files */ for (lp = l_top; lp; lp = lp->l_next) { lockfile = lp->l_lock; #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); @@ -621,7 +594,7 @@ alrmser (int sig) } /* restart the alarm */ - alarm (NSECS); + alarm(NSECS); } #endif /* DOT_LOCKING */