Annotation of 43BSD/contrib/mh/zotnet/mts/lock.c, revision 1.1.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.