Annotation of 43BSDReno/contrib/mh/zotnet/mts/lock.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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