Annotation of lucent/sys/src/9/port/sysproc.c, revision 1.1.1.1

1.1       root        1: #include       "u.h"
                      2: #include       "../port/lib.h"
                      3: #include       "mem.h"
                      4: #include       "dat.h"
                      5: #include       "fns.h"
                      6: #include       "../port/error.h"
                      7: 
                      8: #include       <a.out.h>
                      9: 
                     10: int    shargs(char*, int, char**);
                     11: 
                     12: long
                     13: sysr1(ulong *arg)
                     14: {
                     15:        xsummary();
                     16:        print("[%s %s %d] r1 = %d\n", u->p->user, u->p->text, u->p->pid, arg[0]);
                     17:        return 0;
                     18: }
                     19: 
                     20: long
                     21: sysrfork(ulong *arg)
                     22: {
                     23:        KMap *k;
                     24:        Pgrp *opg;
                     25:        Egrp *oeg;
                     26:        Fgrp *ofg;
                     27:        int n, i;
                     28:        Proc *p, *parent;
                     29:        ulong upa, pid, flag;
                     30:        /*
                     31:         * used to compute last valid system stack address for copy
                     32:         */
                     33:        int lastvar;    
                     34: 
                     35:        flag = arg[0];
                     36:        p = u->p;
                     37:        if((flag&RFPROC) == 0) {
                     38:                if(flag & (RFNAMEG|RFCNAMEG)) {
                     39:                        if((flag & (RFNAMEG|RFCNAMEG)) == (RFNAMEG|RFCNAMEG))
                     40:                                error(Ebadarg);
                     41:                        opg = p->pgrp;
                     42:                        p->pgrp = newpgrp();
                     43:                        if(flag & RFNAMEG)
                     44:                                pgrpcpy(p->pgrp, opg);
                     45:                        closepgrp(opg);
                     46:                }
                     47:                if(flag & (RFENVG|RFCENVG)) {
                     48:                        if((flag & (RFENVG|RFCENVG)) == (RFENVG|RFCENVG))
                     49:                                error(Ebadarg);
                     50:                        oeg = p->egrp;
                     51:                        p->egrp = smalloc(sizeof(Egrp));
                     52:                        p->egrp->ref = 1;
                     53:                        if(flag & RFENVG)
                     54:                                envcpy(p->egrp, oeg);
                     55:                        closeegrp(oeg);
                     56:                }
                     57:                if(flag & RFFDG) {
                     58:                        ofg = p->fgrp;
                     59:                        p->fgrp = dupfgrp(ofg);
                     60:                        closefgrp(ofg);
                     61:                }
                     62:                else
                     63:                if(flag & RFCFDG) {
                     64:                        ofg = p->fgrp;
                     65:                        p->fgrp = smalloc(sizeof(Fgrp));
                     66:                        p->fgrp->ref = 1;
                     67:                        closefgrp(ofg);
                     68:                }
                     69:                if(flag & RFNOTEG)
                     70:                        p->noteid = incref(&noteidalloc);
                     71:                if(flag & (RFMEM|RFNOWAIT))
                     72:                        error(Ebadarg);
                     73:                return 0;
                     74:        }
                     75:        /* Check flags before we commit */
                     76:        if((flag & (RFFDG|RFCFDG)) == (RFFDG|RFCFDG))
                     77:                error(Ebadarg);
                     78:        if((flag & (RFNAMEG|RFCNAMEG)) == (RFNAMEG|RFCNAMEG))
                     79:                error(Ebadarg);
                     80:        if((flag & (RFENVG|RFCENVG)) == (RFENVG|RFCENVG))
                     81:                error(Ebadarg);
                     82: 
                     83:        p = newproc();
                     84:        parent = u->p;
                     85: 
                     86:        /* Page va of upage used as check in mapstack */
                     87:        p->upage = newpage(0, 0, USERADDR|(p->pid&0xFFFF));
                     88:        k = kmap(p->upage);
                     89:        upa = VA(k);
                     90: 
                     91:        /* Save time: only copy u-> data and useful stack */
                     92:        memmove((void*)upa, u, sizeof(User));
                     93:        n = USERADDR+BY2PG - (ulong)&lastvar;
                     94:        n = (n+32) & ~(BY2WD-1);
                     95:        memmove((void*)(upa+BY2PG-n), (void*)(USERADDR+BY2PG-n), n);
                     96:        ((User *)upa)->p = p;
                     97:        kunmap(k);
                     98: 
                     99:        /* Make a new set of memory segments */
                    100:        n = flag & RFMEM;
                    101:        for(i = 0; i < NSEG; i++)
                    102:                if(parent->seg[i])
                    103:                        p->seg[i] = dupseg(parent->seg, i, n);
                    104:        
                    105:        /* Refs */
                    106:        incref(u->dot); 
                    107: 
                    108:        /* File descriptors */
                    109:        if(flag & (RFFDG|RFCFDG)) {
                    110:                if(flag & RFFDG)
                    111:                        p->fgrp = dupfgrp(parent->fgrp);
                    112:                else {
                    113:                        p->fgrp = smalloc(sizeof(Fgrp));
                    114:                        p->fgrp->ref = 1;
                    115:                }
                    116:        }
                    117:        else {
                    118:                p->fgrp = parent->fgrp;
                    119:                incref(p->fgrp);
                    120:        }
                    121: 
                    122:        /* Process groups */
                    123:        if(flag & (RFNAMEG|RFCNAMEG)) { 
                    124:                p->pgrp = newpgrp();
                    125:                if(flag & RFNAMEG)
                    126:                        pgrpcpy(p->pgrp, parent->pgrp);
                    127:        }
                    128:        else {
                    129:                p->pgrp = parent->pgrp;
                    130:                incref(p->pgrp);
                    131:        }
                    132: 
                    133:        /* Environment group */
                    134:        if(flag & (RFENVG|RFCENVG)) {
                    135:                p->egrp = smalloc(sizeof(Egrp));
                    136:                p->egrp->ref = 1;
                    137:                if(flag & RFENVG)
                    138:                        envcpy(p->egrp, parent->egrp);
                    139:        }
                    140:        else {
                    141:                p->egrp = parent->egrp;
                    142:                incref(p->egrp);
                    143:        }
                    144: 
                    145:        p->hang = parent->hang;
                    146:        p->procmode = parent->procmode;
                    147: 
                    148:        if(setlabel(&p->sched)){
                    149:                /*
                    150:                 *  use u->p instead of p, because we don't trust the compiler, after a
                    151:                 *  gotolabel, to find the correct contents of a local variable.
                    152:                 */
                    153:                p = u->p;
                    154:                p->state = Running;
                    155:                p->mach = m;
                    156:                m->proc = p;
                    157:                spllo();
                    158:                return 0;
                    159:        }
                    160: 
                    161:        p->parent = parent;
                    162:        p->parentpid = parent->pid;
                    163:        if(flag&RFNOWAIT)
                    164:                p->parentpid = 1;
                    165:        else {
                    166:                lock(&parent->exl);
                    167:                parent->nchild++;
                    168:                unlock(&parent->exl);
                    169:        }
                    170:        if((flag&RFNOTEG) == 0)
                    171:                p->noteid = parent->noteid;
                    172: 
                    173:        p->fpstate = parent->fpstate;
                    174:        pid = p->pid;
                    175:        memset(p->time, 0, sizeof(p->time));
                    176:        p->time[TReal] = MACHP(0)->ticks;
                    177:        memmove(p->text, parent->text, NAMELEN);
                    178:        memmove(p->user, parent->user, NAMELEN);
                    179:        /*
                    180:         *  since the bss/data segments are now shareable,
                    181:         *  any mmu info about this process is now stale
                    182:         *  (i.e. has bad properties) and has to be discarded.
                    183:         */
                    184:        flushmmu();
                    185:        p->priority = u->p->priority;
                    186:        p->basepri = u->p->basepri;
                    187:        p->mp = u->p->mp;
                    188:        ready(p);
                    189:        sched();
                    190:        return pid;
                    191: }
                    192: 
                    193: static ulong
                    194: l2be(long l)
                    195: {
                    196:        uchar *cp;
                    197: 
                    198:        cp = (uchar*)&l;
                    199:        return (cp[0]<<24) | (cp[1]<<16) | (cp[2]<<8) | cp[3];
                    200: }
                    201: 
                    202: long
                    203: sysexec(ulong *arg)
                    204: {
                    205:        Proc *p;
                    206:        Segment *s, *ts;
                    207:        ulong t, d, b;
                    208:        int i;
                    209:        Chan *tc;
                    210:        char **argv, **argp;
                    211:        char *a, *charp, *file;
                    212:        char *progarg[sizeof(Exec)/2+1], elem[NAMELEN];
                    213:        ulong ssize, spage, nargs, nbytes, n, bssend;
                    214:        int indir;
                    215:        Exec exec;
                    216:        char line[sizeof(Exec)];
                    217:        Fgrp *f;
                    218:        Image *img;
                    219:        ulong magic, text, entry, data, bss;
                    220: 
                    221:        p = u->p;
                    222:        validaddr(arg[0], 1, 0);
                    223:        file = (char*)arg[0];
                    224:        indir = 0;
                    225:     Header:
                    226:        tc = namec(file, Aopen, OEXEC, 0);
                    227:        if(waserror()){
                    228:                close(tc);
                    229:                nexterror();
                    230:        }
                    231:        if(!indir)
                    232:                strcpy(elem, u->elem);
                    233: 
                    234:        n = (*devtab[tc->type].read)(tc, &exec, sizeof(Exec), 0);
                    235:        if(n < 2)
                    236:     Err:
                    237:                error(Ebadexec);
                    238:        magic = l2be(exec.magic);
                    239:        text = l2be(exec.text);
                    240:        entry = l2be(exec.entry);
                    241:        if(n==sizeof(Exec) && magic==AOUT_MAGIC){
                    242:                if((text&KZERO)
                    243:                || entry < UTZERO+sizeof(Exec)
                    244:                || entry >= UTZERO+sizeof(Exec)+text)
                    245:                        goto Err;
                    246:                goto Binary;
                    247:        }
                    248: 
                    249:        /*
                    250:         * Process #! /bin/sh args ...
                    251:         */
                    252:        memmove(line, &exec, sizeof(Exec));
                    253:        if(indir || line[0]!='#' || line[1]!='!')
                    254:                goto Err;
                    255:        n = shargs(line, n, progarg);
                    256:        if(n == 0)
                    257:                goto Err;
                    258:        indir = 1;
                    259:        /*
                    260:         * First arg becomes complete file name
                    261:         */
                    262:        progarg[n++] = file;
                    263:        progarg[n] = 0;
                    264:        validaddr(arg[1], BY2WD, 1);
                    265:        arg[1] += BY2WD;
                    266:        file = progarg[0];
                    267:        progarg[0] = elem;
                    268:        poperror();
                    269:        close(tc);
                    270:        goto Header;
                    271: 
                    272:     Binary:
                    273:        poperror();
                    274:        data = l2be(exec.data);
                    275:        bss = l2be(exec.bss);
                    276:        t = (UTZERO+sizeof(Exec)+text+(BY2PG-1)) & ~(BY2PG-1);
                    277:        d = (t + data + (BY2PG-1)) & ~(BY2PG-1);
                    278:        bssend = t + data + bss;
                    279:        b = (bssend + (BY2PG-1)) & ~(BY2PG-1);
                    280:        if((t|d|b) & KZERO)
                    281:                error(Ebadexec);
                    282: 
                    283:        /*
                    284:         * Args: pass 1: count
                    285:         */
                    286:        nbytes = BY2WD;         /* hole for profiling clock at top of stack */
                    287:        nargs = 0;
                    288:        if(indir){
                    289:                argp = progarg;
                    290:                while(*argp){
                    291:                        a = *argp++;
                    292:                        nbytes += strlen(a) + 1;
                    293:                        nargs++;
                    294:                }
                    295:        }
                    296:        evenaddr(arg[1]);
                    297:        argp = (char**)arg[1];
                    298:        validaddr((ulong)argp, BY2WD, 0);
                    299:        while(*argp){
                    300:                a = *argp++;
                    301:                if(((ulong)argp&(BY2PG-1)) < BY2WD)
                    302:                        validaddr((ulong)argp, BY2WD, 0);
                    303:                validaddr((ulong)a, 1, 0);
                    304:                nbytes += (vmemchr(a, 0, 0x7FFFFFFF) - a) + 1;
                    305:                nargs++;
                    306:        }
                    307:        ssize = BY2WD*(nargs+1) + ((nbytes+(BY2WD-1)) & ~(BY2WD-1));
                    308: 
                    309:        /*
                    310:         * 8-byte align SP for those (e.g. sparc) that need it.
                    311:         * execregs() will subtract another 4 bytes for argc.
                    312:         */
                    313:        if((ssize+4) & 7)
                    314:                ssize += 4;
                    315:        spage = (ssize+(BY2PG-1)) >> PGSHIFT;
                    316:        /*
                    317:         * Build the stack segment, putting it in kernel virtual for the moment
                    318:         */
                    319:        if(spage > TSTKSIZ)
                    320:                error(Enovmem);
                    321: 
                    322:        p->seg[ESEG] = newseg(SG_STACK, TSTKTOP-USTKSIZE, USTKSIZE/BY2PG);
                    323: 
                    324:        /*
                    325:         * Args: pass 2: assemble; the pages will be faulted in
                    326:         */
                    327:        argv = (char**)(TSTKTOP - ssize);
                    328:        charp = (char*)(TSTKTOP - nbytes);
                    329:        if(indir)
                    330:                argp = progarg;
                    331:        else
                    332:                argp = (char**)arg[1];
                    333: 
                    334:        for(i=0; i<nargs; i++){
                    335:                if(indir && *argp==0) {
                    336:                        indir = 0;
                    337:                        argp = (char**)arg[1];
                    338:                }
                    339:                *argv++ = charp + (USTKTOP-TSTKTOP);
                    340:                n = strlen(*argp) + 1;
                    341:                memmove(charp, *argp++, n);
                    342:                charp += n;
                    343:        }
                    344: 
                    345:        memmove(p->text, elem, NAMELEN);
                    346: 
                    347:        /*
                    348:         * Committed.
                    349:         * Free old memory.
                    350:         * Special segments are maintained accross exec
                    351:         */
                    352:        for(i = SSEG; i <= BSEG; i++) {
                    353:                putseg(p->seg[i]);
                    354:                /* prevent a second free if we have an error */
                    355:                p->seg[i] = 0;     
                    356:        }
                    357:        for(i = BSEG+1; i < NSEG; i++) {
                    358:                s = p->seg[i];
                    359:                if(s != 0 && (s->type&SG_CEXEC)) {
                    360:                        putseg(s);
                    361:                        p->seg[i] = 0;
                    362:                }
                    363:        }
                    364: 
                    365:        /*
                    366:         * Close on exec
                    367:         */
                    368:        f = u->p->fgrp;
                    369:        for(i=0; i<=f->maxfd; i++)
                    370:                fdclose(i, CCEXEC);
                    371: 
                    372:        /* Text.  Shared. Attaches to cache image if possible */
                    373:        /* attachimage returns a locked cache image */
                    374:        img = attachimage(SG_TEXT|SG_RONLY, tc, UTZERO, (t-UTZERO)>>PGSHIFT);
                    375:        ts = img->s;
                    376:        p->seg[TSEG] = ts;
                    377:        ts->flushme = 1;
                    378:        ts->fstart = 0;
                    379:        ts->flen = sizeof(Exec)+text;
                    380:        unlock(img);
                    381: 
                    382:        /* Data. Shared. */
                    383:        s = newseg(SG_DATA, t, (d-t)>>PGSHIFT);
                    384:        p->seg[DSEG] = s;
                    385: 
                    386:        /* Attached by hand */
                    387:        incref(img);
                    388:        s->image = img;
                    389:        s->fstart = ts->fstart+ts->flen;
                    390:        s->flen = data;
                    391: 
                    392:        /* BSS. Zero fill on demand */
                    393:        p->seg[BSEG] = newseg(SG_BSS, d, (b-d)>>PGSHIFT);
                    394: 
                    395:        /*
                    396:         * Move the stack
                    397:         */
                    398:        s = p->seg[ESEG];
                    399:        p->seg[ESEG] = 0;
                    400:        p->seg[SSEG] = s;
                    401:        s->base = USTKTOP-USTKSIZE;
                    402:        s->top = USTKTOP;
                    403:        relocateseg(s, TSTKTOP-USTKTOP);
                    404: 
                    405:        /*
                    406:         *  '/' processes are higher priority (hack to make /ip more responsive).
                    407:         */
                    408:        if(devchar[tc->type] == L'/')
                    409:                u->p->basepri = PriRoot;
                    410:        u->p->priority = u->p->basepri;
                    411:        close(tc);
                    412: 
                    413:        /*
                    414:         *  At this point, the mmu contains info about the old address
                    415:         *  space and needs to be flushed
                    416:         */
                    417:        flushmmu();
                    418:        qlock(&p->debug);
                    419:        u->nnote = 0;
                    420:        u->notify = 0;
                    421:        u->notified = 0;
                    422:        procsetup(p);
                    423:        qunlock(&p->debug);
                    424:        if(p->hang)
                    425:                p->procctl = Proc_stopme;
                    426: 
                    427:        return execregs(entry, ssize, nargs);
                    428: }
                    429: 
                    430: int
                    431: shargs(char *s, int n, char **ap)
                    432: {
                    433:        int i;
                    434: 
                    435:        s += 2;
                    436:        n -= 2;         /* skip #! */
                    437:        for(i=0; s[i]!='\n'; i++)
                    438:                if(i == n-1)
                    439:                        return 0;
                    440:        s[i] = 0;
                    441:        *ap = 0;
                    442:        i = 0;
                    443:        for(;;){
                    444:                while(*s==' ' || *s=='\t')
                    445:                        s++;
                    446:                if(*s == 0)
                    447:                        break;
                    448:                i++;
                    449:                *ap++ = s;
                    450:                *ap = 0;
                    451:                while(*s && *s!=' ' && *s!='\t')
                    452:                        s++;
                    453:                if(*s == 0)
                    454:                        break;
                    455:                else
                    456:                        *s++ = 0;
                    457:        }
                    458:        return i;
                    459: }
                    460: 
                    461: int
                    462: return0(void *a)
                    463: {
                    464:        USED(a);
                    465:        return 0;
                    466: }
                    467: 
                    468: long
                    469: syssleep(ulong *arg)
                    470: {
                    471:        int n;
                    472: 
                    473:        n = arg[0];
                    474:        if(n == 0){
                    475:                sched();        /* yield */
                    476:                return 0;
                    477:        }
                    478:        if(MS2TK(n) == 0)       /* sleep for at least one tick */
                    479:                n = TK2MS(1);
                    480:        tsleep(&u->p->sleep, return0, 0, n);
                    481: 
                    482:        return 0;
                    483: }
                    484: 
                    485: long
                    486: sysalarm(ulong *arg)
                    487: {
                    488:        return procalarm(arg[0]);               
                    489: }
                    490: 
                    491: long
                    492: sysexits(ulong *arg)
                    493: {
                    494:        char *status;
                    495:        char *inval = "invalid exit string";
                    496:        char buf[ERRLEN];
                    497: 
                    498:        status = (char*)arg[0];
                    499:        if(status){
                    500:                if(waserror())
                    501:                        status = inval;
                    502:                else{
                    503:                        validaddr((ulong)status, 1, 0);
                    504:                        if(vmemchr(status, 0, ERRLEN) == 0){
                    505:                                memmove(buf, status, ERRLEN);
                    506:                                buf[ERRLEN-1] = 0;
                    507:                                status = buf;
                    508:                        }
                    509:                }
                    510:                poperror();
                    511: 
                    512:        }
                    513:        pexit(status, 1);
                    514:        return 0;               /* not reached */
                    515: }
                    516: 
                    517: long
                    518: syswait(ulong *arg)
                    519: {
                    520:        if(arg[0]){
                    521:                validaddr(arg[0], sizeof(Waitmsg), 1);
                    522:                evenaddr(arg[0]);
                    523:        }
                    524:        return pwait((Waitmsg*)arg[0]);
                    525: }
                    526: 
                    527: long
                    528: sysdeath(ulong *arg)
                    529: {
                    530:        USED(arg);
                    531:        pprint("deprecated system call\n");
                    532:        pexit("Suicide", 0);
                    533:        return 0;       /* not reached */
                    534: }
                    535: 
                    536: long
                    537: syserrstr(ulong *arg)
                    538: {
                    539:        char tmp[ERRLEN];
                    540: 
                    541:        validaddr(arg[0], ERRLEN, 1);
                    542:        memmove(tmp, (char*)arg[0], ERRLEN);
                    543:        memmove((char*)arg[0], u->error, ERRLEN);
                    544:        memmove(u->error, tmp, ERRLEN);
                    545:        return 0;
                    546: }
                    547: 
                    548: long
                    549: sysnotify(ulong *arg)
                    550: {
                    551:        USED(arg);
                    552:        if(arg[0] != 0)
                    553:                validaddr(arg[0], sizeof(ulong), 0);
                    554:        u->notify = (int(*)(void*, char*))(arg[0]);
                    555:        return 0;
                    556: }
                    557: 
                    558: long
                    559: sysnoted(ulong *arg)
                    560: {
                    561:        if(arg[0]!=NRSTR && !u->notified)
                    562:                error(Egreg);
                    563:        return 0;
                    564: }
                    565: 
                    566: long
                    567: syssegbrk(ulong *arg)
                    568: {
                    569:        Segment *s;
                    570:        int i;
                    571: 
                    572:        for(i = 0; i < NSEG; i++) {
                    573:                if(s = u->p->seg[i]) {
                    574:                        if(arg[0] >= s->base && arg[0] < s->top) {
                    575:                                switch(s->type&SG_TYPE) {
                    576:                                case SG_TEXT:
                    577:                                case SG_DATA:
                    578:                                case SG_STACK:
                    579:                                        error(Ebadarg);
                    580:                                default:
                    581:                                        return ibrk(arg[1], i);
                    582:                                }
                    583:                        }
                    584:                }
                    585:        }
                    586: 
                    587:        error(Ebadarg);
                    588:        return 0;               /* not reached */
                    589: }
                    590: 
                    591: long
                    592: syssegattach(ulong *arg)
                    593: {
                    594:        return segattach(u->p, arg[0], (char*)arg[1], arg[2], arg[3]);
                    595: }
                    596: 
                    597: long
                    598: syssegdetach(ulong *arg)
                    599: {
                    600:        int i;
                    601:        Segment *s;
                    602: 
                    603:        s = 0;
                    604:        for(i = 0; i < NSEG; i++)
                    605:                if(s = u->p->seg[i]) {
                    606:                        qlock(&s->lk);
                    607:                        if((arg[0] >= s->base && arg[0] < s->top) || 
                    608:                           (s->top == s->base && arg[0] == s->base))
                    609:                                goto found;
                    610:                        qunlock(&s->lk);
                    611:                }
                    612: 
                    613:        error(Ebadarg);
                    614: 
                    615: found:
                    616:        if((ulong)arg >= s->base && (ulong)arg < s->top) {
                    617:                qunlock(&s->lk);
                    618:                error(Ebadarg);
                    619:        }
                    620:        u->p->seg[i] = 0;
                    621:        qunlock(&s->lk);
                    622:        putseg(s);
                    623: 
                    624:        /* Ensure we flush any entries from the lost segment */
                    625:        flushmmu();
                    626:        return 0;
                    627: }
                    628: 
                    629: long
                    630: syssegfree(ulong *arg)
                    631: {
                    632:        Segment *s;
                    633:        ulong from, pages;
                    634: 
                    635:        from = PGROUND(arg[0]);
                    636:        s = seg(u->p, from, 1);
                    637:        if(s == 0)
                    638:                error(Ebadarg);
                    639: 
                    640:        pages = (arg[1]+BY2PG-1)/BY2PG;
                    641: 
                    642:        if(from+pages*BY2PG > s->top) {
                    643:                qunlock(&s->lk);
                    644:                error(Ebadarg);
                    645:        }
                    646: 
                    647:        mfreeseg(s, from, pages);
                    648:        qunlock(&s->lk);
                    649:        flushmmu();
                    650: 
                    651:        return 0;
                    652: }
                    653: 
                    654: /* For binary compatability */
                    655: long
                    656: sysbrk_(ulong *arg)
                    657: {
                    658:        return ibrk(arg[0], BSEG);
                    659: }
                    660: 
                    661: long
                    662: sysrendezvous(ulong *arg)
                    663: {
                    664:        Proc *p, **l;
                    665:        int tag;
                    666:        ulong val;
                    667: 
                    668:        tag = arg[0];
                    669:        l = &REND(u->p->pgrp, tag);
                    670: 
                    671:        lock(u->p->pgrp);
                    672:        for(p = *l; p; p = p->rendhash) {
                    673:                if(p->rendtag == tag) {
                    674:                        *l = p->rendhash;
                    675:                        val = p->rendval;
                    676:                        p->rendval = arg[1];
                    677:                        /* Hard race avoidance */
                    678:                        while(p->mach != 0)
                    679:                                ;
                    680:                        ready(p);
                    681:                        unlock(u->p->pgrp);
                    682:                        return val;     
                    683:                }
                    684:                l = &p->rendhash;
                    685:        }
                    686: 
                    687:        /* Going to sleep here */
                    688:        p = u->p;
                    689:        p->rendtag = tag;
                    690:        p->rendval = arg[1];
                    691:        p->rendhash = *l;
                    692:        *l = p;
                    693:        u->p->state = Rendezvous;
                    694:        unlock(p->pgrp);
                    695: 
                    696:        sched();
                    697: 
                    698:        return u->p->rendval;
                    699: }

unix.superglobalmegacorp.com

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