|
|
1.1 ! root 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.