|
|
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 l
Length: 3349 (0xd15)
Types: TextFile
Names: »lock.c«
└─⟦2d1937cfd⟧ Bits:30007241 EUUGD22: P.P 5.0
└─⟦dc59850a2⟧ »EurOpenD22/pp5.0/pp-5.tar.Z«
└─⟦e5a54fb17⟧
└─⟦this⟧ »pp-5.0/Lib/util/lock.c«
/* lock.c: file locking subroutines */
# ifndef lint
static char Rcsid[] = "@(#)$Header: /cs/research/pp/hubris/pp-beta/Lib/util/RCS/lock.c,v 5.0 90/09/20 16:17:25 pp Exp Locker: pp $";
# endif
/*
* $Header: /cs/research/pp/hubris/pp-beta/Lib/util/RCS/lock.c,v 5.0 90/09/20 16:17:25 pp Exp Locker: pp $
*
* $Log: lock.c,v $
* Revision 5.0 90/09/20 16:17:25 pp
* rcsforce : 5.0 public release
*
*/
#include "util.h"
#include <sys/file.h>
#if defined(SUNOS4) || defined(SYS5)
#include <sys/fcntl.h>
#endif
#if defined(sun) || defined(SYS5)
#include <unistd.h>
#endif
#include <sys/stat.h>
static int lk_file ();
static int lk_unlck ();
static char *lockfd[FD_SETSIZE];
extern char *lockdir;
extern int lockstyle;
extern int lock_break_time; /* 30 minutes grace ? */
extern time_t time ();
FILE *flckopen (name, mode)
char *name;
char *mode;
{
FILE *fp;
if ((fp = fopen (name, mode)) == NULL)
return NULL;
switch (lockstyle) {
case LOCK_FLOCK:
#ifdef LOCK_EX
if (flock (fileno (fp), LOCK_EX | LOCK_NB) == NOTOK) {
(void) fclose (fp);
return NULL;
}
return fp;
#else
break;
#endif
case LOCK_FCNTL:
#ifdef F_RDLCK
{
struct flock l;
l.l_len = 0;
l.l_start = 0;
l.l_whence = 0;
if (*mode == 'r' && mode[1] != '+')
l.l_type = F_RDLCK;
else
l.l_type = F_WRLCK;
if (fcntl (fileno(fp), F_SETLK, &l) < 0) {
(void) fclose (fp);
return NULL;
}
}
return fp;
#else
break;
#endif
case LOCK_LOCKF:
#ifdef F_TLOCK
if (lockf (fileno (fp), F_TLOCK, 0L) == NOTOK) {
(void) fclose (fp);
return NULL;
}
return fp;
#else
break;
#endif
default:
case LOCK_FILE:
if (lk_file (name, fileno (fp)) == NOTOK) {
(void) fclose (fp);
return NULL;
}
break;
}
PP_OPER (NULLCP, ("Specified styple of locking (%d) not supported",
lockstyle));
return NULL;
}
static int lk_file (name, n)
char *name;
int n;
{
char locktmp[FILNSIZE];
char lockname[FILNSIZE];
struct stat st;
int fd;
time_t now;
if (n < 0 || n >= FD_SETSIZE)
return NOTOK;
if (fstat (n, &st) == NOTOK) {
PP_SLOG (LLOG_EXCEPTIONS, name, ("Can't fstat %d file", n));
return NOTOK;
}
(void) sprintf (locktmp, "%s/LCK%05.5o+%o.t", lockdir,
st.st_dev, st.st_ino);
(void) sprintf (lockname, "%s/LCK%05.5o+%o",
lockdir, st.st_dev, st.st_ino);
if ((fd = open (locktmp, O_RDWR|O_CREAT, 0)) < 0) {
PP_SLOG (LLOG_EXCEPTIONS, locktmp,
("Can't create lock temp file"));
return NOTOK;
}
(void) close (fd);
if (stat (lockname, &st) != NOTOK) {
(void) time (&now);
if (st.st_mtime + lock_break_time < now) {
PP_NOTICE (("Forcing lock for %s", lockname));
(void) unlink (lockname);
}
}
if (link (locktmp, lockname) == NOTOK) {
PP_SLOG (LLOG_EXCEPTIONS, lockname,
("Can't lock by linking %s to ", locktmp));
(void) unlink (locktmp);
return NOTOK;
}
(void) unlink (locktmp);
lockfd[n] = strdup (lockname);
return OK;
}
int flckclose (fp)
FILE *fp;
{
switch (lockstyle) {
case LOCK_FCNTL:
case LOCK_FLOCK:
return fclose (fp);
default:
case LOCK_FILE:
return lk_unlck (fp);
}
}
static int lk_unlck (fp)
FILE *fp;
{
int n = fileno (fp);
if (n >= 0 && n < FD_SETSIZE && lockfd[n] && *lockfd[n]) {
(void) unlink (lockfd[n]);
lockfd[n] = NULLCP;
return OK;
}
return NOTOK;
}