1: /* lock.c - universal locking routines */
   2: 
   3: #ifndef MMDFONLY
   4: #include "../h/strings.h"
   5: #else   MMDFONLY
   6: #include "strings.h"
   7: #include "mmdfonly.h"
   8: #endif	MMDFONLY
   9: #include <stdio.h>
  10: #include "mts.h"
  11: #include <sys/types.h>
  12: #include <sys/stat.h>
  13: 
  14: 
  15: #define NOTOK   (-1)
  16: #define OK  0
  17: 
  18: #define NULLCP  ((char *) 0)
  19: 
  20: #ifdef  SYS5
  21: #define index   strchr
  22: #define rindex  strrchr
  23: #endif	SYS5
  24: 
  25: 
  26: extern int  errno;
  27: 
  28: /*  */
  29: 
  30: int lkopen (file, access)
  31: register char   *file;
  32: register int     access;
  33: {
  34:     mts_init ("mts");
  35:     switch (lockstyle) {
  36:     case LOK_UNIX:
  37: #ifdef  BSD42
  38:         return f_lkopen (file, access);
  39: #endif	BSD42
  40: 
  41:     default:
  42:         return b_lkopen (file, access);
  43:     }
  44: }
  45: 
  46: /*  */
  47: 
  48: static int  b_lkopen (file, access)
  49: register char   *file;
  50: register int     access;
  51: {
  52:     register int    i,
  53:                     j;
  54:     long    curtime;
  55:     char    curlock[BUFSIZ],
  56:             tmplock[BUFSIZ];
  57:     struct stat st;
  58: 
  59:     if (stat (file, &st) == NOTOK)
  60:     return NOTOK;
  61:     lockname (curlock, tmplock, file, (int) st.st_dev, (int) st.st_ino);
  62: 
  63:     for (i = 0;;)
  64:     switch (lockit (tmplock, curlock)) {
  65:         case OK:
  66:         if ((i = open (file, access)) == NOTOK) {
  67:             j = errno;
  68:             (void) unlink (curlock);
  69:             errno = j;
  70:         }
  71:         timerON (curlock, i);
  72:         return i;
  73: 
  74:         case NOTOK:
  75:         if (stat (curlock, &st) == NOTOK) {
  76:             if (i++ > 5)
  77:             return NOTOK;
  78:             sleep (5);
  79:             break;
  80:         }
  81: 
  82:         i = 0;
  83:         (void) time (&curtime);
  84:         if (curtime < st.st_ctime + 60L)
  85:             sleep (5);
  86:         else
  87:             (void) unlink (curlock);
  88:         break;
  89:     }
  90: }
  91: 
  92: 
  93: static int  lockit (tmp, file)
  94: register char   *tmp,
  95:             *file;
  96: {
  97:     register int    fd;
  98: 
  99:     if ((fd = creat (tmp, 0400)) == NOTOK)
 100:     return NOTOK;
 101:     (void) close (fd);
 102: 
 103:     fd = link (tmp, file);
 104:     (void) unlink (tmp);
 105: 
 106:     return (fd != NOTOK ? OK : NOTOK);
 107: }
 108: 
 109: /*  */
 110: 
 111: static  lockname (curlock, tmplock, file, dev, ino)
 112: register char   *curlock,
 113:             *tmplock,
 114:             *file;
 115: register int     dev,
 116:          ino;
 117: {
 118:     register char  *bp,
 119:                    *cp;
 120: 
 121:     bp = curlock;
 122:     if ((cp = rindex (file, '/')) == NULL || *++cp == NULL)
 123:     cp = file;
 124:     if (lockldir == NULL || *lockldir == NULL) {
 125:     if (cp != file) {
 126:         (void) sprintf (bp, "%.*s", cp - file, file);
 127:         bp += strlen (bp);
 128:     }
 129:     }
 130:     else {
 131:     (void) sprintf (bp, "%s/", lockldir);
 132:     bp += strlen (bp);
 133:     }
 134: 
 135:     switch (lockstyle) {
 136:     case LOK_BELL:
 137:     default:
 138:         (void) sprintf (bp, "%s.lock", cp);
 139:         break;
 140: 
 141:     case LOK_MMDF:
 142:         (void) sprintf (bp, "LCK%05d.%05d", dev, ino);
 143:         break;
 144:     }
 145: 
 146:     if (tmplock) {
 147:     if ((cp = rindex (curlock, '/')) == NULL || *++cp == NULL)
 148:         (void) strcpy (tmplock, ",LCK.XXXXXX");
 149:     else
 150:         (void) sprintf (tmplock, "%.*s,LCK.XXXXXX",
 151:         cp - curlock, curlock);
 152:     (void) unlink (mktemp (tmplock));
 153:     }
 154: }
 155: 
 156: /*  */
 157: 
 158: #ifdef  BSD42
 159: 
 160: #include <sys/file.h>
 161: 
 162: static int  f_lkopen (file, access)
 163: register char   *file;
 164: register int     access;
 165: {
 166:     register int    fd,
 167:                     i,
 168:             j;
 169: 
 170:     for (i = 0; i < 5; i++) {
 171:     if ((fd = open (file, access | O_NDELAY)) == NOTOK)
 172:         return NOTOK;
 173:     if (flock (fd, LOCK_EX | LOCK_NB) != NOTOK)
 174:         return fd;
 175:     j = errno;
 176:     (void) close (fd);
 177: 
 178:     sleep (5);
 179:     }
 180: 
 181:     (void) close (fd);
 182:     errno = j;
 183:     return NOTOK;
 184: }
 185: #endif	BSD42
 186: 
 187: /*  */
 188: 
 189: /* ARGSUSED */
 190: 
 191: int     lkclose (fd, file)
 192: register int     fd;
 193: register char   *file;
 194: {
 195:     char    curlock[BUFSIZ];
 196:     struct stat st;
 197: 
 198:     if (fd == NOTOK)
 199:     return OK;
 200:     switch (lockstyle) {
 201:     case LOK_UNIX:
 202: #ifdef  BSD42
 203:         break;
 204: #endif	BSD42
 205: 
 206:     default:
 207:         if (fstat (fd, &st) != NOTOK) {
 208:         lockname (curlock, NULLCP, file, (int) st.st_dev, (int) st.st_ino);
 209:         (void) unlink (curlock);
 210:         timerOFF (fd);
 211:         }
 212:     }
 213: 
 214:     return (close (fd));
 215: }
 216: 
 217: 
 218: /*  */
 219: 
 220: FILE    *lkfopen (file, mode)
 221: register char   *file,
 222:             *mode;
 223: {
 224:     register int    fd;
 225:     register FILE  *fp;
 226: 
 227:     if ((fd = lkopen (file, strcmp (mode, "r") ? 2 : 0)) == NOTOK)
 228:     return NULL;
 229: 
 230:     if ((fp = fdopen (fd, mode)) == NULL) {
 231:     (void) close (fd);
 232:     return NULL;
 233:     }
 234: 
 235:     return fp;
 236: }
 237: 
 238: 
 239: /* ARGSUSED */
 240: 
 241: int lkfclose (fp, file)
 242: register FILE   *fp;
 243: register char   *file;
 244: {
 245:     char    curlock[BUFSIZ];
 246:     struct stat st;
 247: 
 248:     if (fp == NULL)
 249:     return OK;
 250: 
 251:     switch (lockstyle) {
 252:     case LOK_UNIX:
 253: #ifdef  BSD42
 254:         break;
 255: #endif	BSD42
 256: 
 257:     default:
 258:         if (fstat (fileno (fp), &st) != NOTOK) {
 259:         lockname (curlock, NULLCP, file, (int) st.st_dev, (int) st.st_ino);
 260:         (void) unlink (curlock);
 261:         }
 262:     }
 263: 
 264:     return (fclose (fp));
 265: }
 266: 
 267: /*  */
 268: 
 269: #include <signal.h>
 270: 
 271: #define NSECS   ((unsigned) 20)
 272: 
 273: 
 274: struct lock {
 275:     int      l_fd;
 276:     char    *l_lock;
 277:     struct lock *l_next;
 278: };
 279: #define NULLP   ((struct lock *) 0)
 280: 
 281: static struct lock *l_top = NULLP;
 282: 
 283: 
 284: /* ARGSUSED */
 285: 
 286: static alrmser (sig)
 287: int sig;
 288: {
 289:     register int    j;
 290:     register char  *cp;
 291:     register struct lock   *lp;
 292: 
 293: #ifndef BSD42
 294:     (void) signal (SIGALRM, alrmser);
 295: #endif	BSD42
 296: 
 297:     for (lp = l_top; lp; lp = lp -> l_next)
 298:     if (*(cp = lp -> l_lock) && (j = creat (cp, 0400)) != NOTOK)
 299:         (void) close (j);
 300: 
 301:     (void) alarm (NSECS);
 302: }
 303: 
 304: /*  */
 305: 
 306: static timerON (lock, fd)
 307: char   *lock;
 308: int fd;
 309: {
 310:     register struct lock   *lp;
 311: 
 312:     if ((lp = (struct lock *) malloc ((unsigned) (sizeof *lp))) == NULLP)
 313:     return;         /* XXX */
 314: 
 315:     lp -> l_fd = fd;
 316:     if ((lp -> l_lock = malloc ((unsigned) (strlen (lock) + 1))) == NULLCP) {
 317:     free ((char *) lp);
 318:     return;         /* XXX */
 319:     }
 320:     (void) strcpy (lp -> l_lock, lock);
 321:     lp -> l_next = NULLP;
 322: 
 323:     if (l_top)
 324:     lp -> l_next = l_top -> l_next;
 325:     else {
 326:     (void) signal (SIGALRM, alrmser);/* perhaps SIGT{STP,TIN,TOU} */
 327:     (void) alarm (NSECS);
 328:     }
 329:     l_top = lp;
 330: }
 331: 
 332: 
 333: static timerOFF (fd)
 334: int fd;
 335: {
 336:     register struct lock   *pp,
 337:                            *lp;
 338: 
 339:     (void) alarm (0);
 340: 
 341:     if (l_top) {
 342:     for (pp = lp = l_top; lp; pp = lp, lp = lp -> l_next)
 343:         if (lp -> l_fd == fd)
 344:         break;
 345:     if (lp) {
 346:         if (lp == l_top)
 347:         l_top = lp -> l_next;
 348:         else
 349:         pp -> l_next = lp -> l_next;
 350: 
 351:         free (lp -> l_lock);
 352:         free ((char *) lp);
 353:     }
 354:     }
 355: 
 356:     if (l_top)
 357:     (void) alarm (NSECS);
 358: }

Defined functions

alrmser defined in line 286; used 2 times
b_lkopen defined in line 48; used 1 times
  • in line 42
f_lkopen defined in line 162; used 1 times
  • in line 38
lkfopen defined in line 220; used 1 times
lockit defined in line 93; used 1 times
  • in line 64
lockname defined in line 111; used 3 times
timerOFF defined in line 333; used 1 times
timerON defined in line 306; used 1 times
  • in line 71

Defined variables

l_top defined in line 281; used 9 times

Defined struct's

lock defined in line 274; used 12 times

Defined macros

NOTOK defined in line 15; used 18 times
NSECS defined in line 271; used 3 times
NULLCP defined in line 18; used 3 times
NULLP defined in line 279; used 3 times
OK defined in line 16; used 3 times
index defined in line 21; never used
rindex defined in line 22; used 2 times
Last modified: 1986-04-21
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2012
Valid CSS Valid XHTML 1.0 Strict