|
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; }