Annotation of 43BSD/contrib/mh/zotnet/mts/lock.c, revision 1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.