Annotation of lucent/sys/src/9/port/sysproc.c, revision 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.