|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T m
Length: 4022 (0xfb6)
Types: TextFile
Names: »mhlock.c«
└─⟦9ae75bfbd⟧ Bits:30007242 EUUGD3: Starter Kit
└─⟦bfebc70e2⟧ »EurOpenD3/mail/sendmail-5.65b+IDA-1.4.3.tar.Z«
└─⟦f9e35cd84⟧
└─⟦this⟧ »sendmail/binmail/mhlock.c«
/* 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);
}
/* \f
*/
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));
}
}
/* \f
*/
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));
}
/* \f
*/
#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);
}
/* \f
*/
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 */