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