home *** CD-ROM | disk | FTP | other *** search
- /* lock.c - universal locking routines */
- #ifndef lint
- static char ident[] = "@(#)$Id: mhlock.c,v 1.1 90/11/23 13:52:46 asjl Exp Locker: asjl $";
- #endif lint
-
- #if defined(MH_LCK_BEL)
-
- #include <stdio.h>
- #include <sys/types.h>
- #include <sys/stat.h>
-
- #define NOTOK (-1)
- #define OK 0
-
- #define NULLCP ((char *) 0)
-
- #ifdef SYS5
- #define index strchr
- #define rindex strrchr
- #endif SYS5
-
- extern int errno;
-
- static int lockit();
- static lockname(), timerON(), timerOFF();
-
- long time ();
-
- int lkopen (file, access)
- register char *file;
- register int access;
- {
- register int i,
- j;
- long curtime;
- char curlock[BUFSIZ],
- tmplock[BUFSIZ];
- struct stat st;
-
- if (stat (file, &st) == NOTOK)
- return NOTOK;
- lockname (curlock, tmplock, file);
-
- for (i = 0;;)
- switch (lockit (tmplock, curlock)) {
- case OK:
- if ((i = open (file, access)) == NOTOK) {
- j = errno;
- (void) unlink (curlock);
- errno = j;
- }
- timerON (curlock, i);
- return i;
-
- case NOTOK:
- if (stat (curlock, &st) == NOTOK) {
- if (i++ > 5)
- return NOTOK;
- sleep (5);
- break;
- }
-
- i = 0;
- (void) time (&curtime);
- if (curtime < st.st_ctime + 60L)
- sleep (5);
- else
- (void) unlink (curlock);
- break;
- }
- }
-
-
- static int lockit (tmp, file)
- register char *tmp,
- *file;
- {
- register int fd;
-
- if ((fd = creat (tmp, 0400)) == NOTOK)
- return NOTOK;
- #ifdef hpux
- write(fd, "binmail lock\n",8);
- #endif hpux
- (void) close (fd);
-
- fd = link (tmp, file);
- (void) unlink (tmp);
-
- return (fd != NOTOK ? OK : NOTOK);
- }
-
- /* */
-
- static lockname (curlock, tmplock, file)
- register char *curlock,
- *tmplock,
- *file;
- {
- register char *cp;
- extern char *rindex();
-
- (void) sprintf (curlock, "%s.lock", file);
-
- if (tmplock)
- {
- if ((cp = rindex (curlock, '/')) == NULL || *++cp == NULL)
- (void) strcpy (tmplock, ",LCK.XXXXXX");
- else
- (void) sprintf (tmplock, "%.*s,LCK.XXXXXX",
- cp - curlock, curlock);
- (void) unlink (mktemp (tmplock));
- }
- }
-
- /* */
-
- int lkclose (fd, file)
- register int fd;
- register char *file;
- {
- char curlock[BUFSIZ];
- struct stat st;
-
- if (fd == NOTOK)
- return OK;
- if (fstat (fd, &st) != NOTOK)
- {
- lockname (curlock, NULLCP, file);
- (void) unlink (curlock);
- timerOFF (fd);
- }
-
- return (close (fd));
- }
-
- /* */
-
- #include <signal.h>
-
- #define NSECS ((unsigned) 20)
-
-
- struct lock {
- int l_fd;
- char *l_lock;
- struct lock *l_next;
- };
- #define NULLP ((struct lock *) 0)
-
- static struct lock *l_top = NULLP;
-
-
- /* ARGSUSED */
-
- static alrmser (sig)
- int sig;
- {
- register int j;
- register char *cp;
- register struct lock *lp;
-
- #ifndef BSD42
- (void) signal (SIGALRM, alrmser);
- #endif BSD42
-
- for (lp = l_top; lp; lp = lp -> l_next)
- if (*(cp = lp -> l_lock) && (j = creat (cp, 0400)) != NOTOK)
- (void) close (j);
-
- (void) alarm (NSECS);
- }
-
- /* */
-
- static timerON (lock, fd)
- char *lock;
- int fd;
- {
- register struct lock *lp;
-
- if ((lp = (struct lock *) malloc ((unsigned) (sizeof *lp))) == NULLP)
- return; /* XXX */
-
- lp -> l_fd = fd;
- if ((lp -> l_lock = malloc ((unsigned) (strlen (lock) + 1))) == NULLCP) {
- free ((char *) lp);
- return; /* XXX */
- }
- (void) strcpy (lp -> l_lock, lock);
- lp -> l_next = NULLP;
-
- if (l_top)
- lp -> l_next = l_top -> l_next;
- else {
- (void) signal (SIGALRM, alrmser);/* perhaps SIGT{STP,TIN,TOU} */
- (void) alarm (NSECS);
- }
- l_top = lp;
- }
-
-
- static timerOFF (fd)
- int fd;
- {
- register struct lock *pp,
- *lp;
-
- (void) alarm (0);
-
- if (l_top) {
- for (pp = lp = l_top; lp; pp = lp, lp = lp -> l_next)
- if (lp -> l_fd == fd)
- break;
- if (lp) {
- if (lp == l_top)
- l_top = lp -> l_next;
- else
- pp -> l_next = lp -> l_next;
-
- free (lp -> l_lock);
- free ((char *) lp);
- }
- }
-
- if (l_top)
- (void) alarm (NSECS);
- }
- #endif /* MH_LCK_BEL */
-