Annotation of lucent/sys/src/9/port/devproc.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: #include       "ureg.h"
        !             8: 
        !             9: #include       "devtab.h"
        !            10: 
        !            11: enum{
        !            12:        Qdir,
        !            13:        Qctl,
        !            14:        Qmem,
        !            15:        Qnote,
        !            16:        Qnoteid,
        !            17:        Qnotepg,
        !            18:        Qproc,
        !            19:        Qsegment,
        !            20:        Qstatus,
        !            21:        Qtext,
        !            22:        Qwait,
        !            23: };
        !            24: 
        !            25: #define        STATSIZE        (2*NAMELEN+12+7*12)
        !            26: Dirtab procdir[] =
        !            27: {
        !            28:        "ctl",          {Qctl},         0,                      0000,
        !            29:        "mem",          {Qmem},         0,                      0000,
        !            30:        "note",         {Qnote},        0,                      0000,
        !            31:        "noteid",       {Qnoteid},      0,                      0666,
        !            32:        "notepg",       {Qnotepg},      0,                      0000,
        !            33:        "proc",         {Qproc},        sizeof(Proc),           0444,
        !            34:        "segment",      {Qsegment},     0,                      0444,
        !            35:        "status",       {Qstatus},      STATSIZE,               0444,
        !            36:        "text",         {Qtext},        0,                      0000,
        !            37:        "wait",         {Qwait},        0,                      0400,
        !            38: };
        !            39: 
        !            40: /* Segment type from portdat.h */
        !            41: char *sname[]={ "Text", "Data", "Bss", "Stack", "Shared", "Phys", "Shdata" };
        !            42: 
        !            43: /*
        !            44:  * Qids are, in path:
        !            45:  *      4 bits of file type (qids above)
        !            46:  *     23 bits of process slot number + 1
        !            47:  *          in vers,
        !            48:  *     32 bits of pid, for consistency checking
        !            49:  * If notepg, c->pgrpid.path is pgrp slot, .vers is noteid.
        !            50:  */
        !            51: #define        NPROC   (sizeof procdir/sizeof(Dirtab))
        !            52: #define        QSHIFT  4       /* location in qid of proc slot # */
        !            53: 
        !            54: #define        QID(q)          (((q).path&0x0000000F)>>0)
        !            55: #define        SLOT(q)         ((((q).path&0x07FFFFFF0)>>QSHIFT)-1)
        !            56: #define        PID(q)          ((q).vers)
        !            57: #define        NOTEID(q)       ((q).vers)
        !            58: 
        !            59: void   procctlreq(Proc*, char*, int);
        !            60: int    procctlmemio(Proc*, ulong, int, void*, int);
        !            61: Chan*  proctext(Chan*, Proc*);
        !            62: Segment* txt2data(Proc*, Segment*);
        !            63: int    procstopped(void*);
        !            64: 
        !            65: int
        !            66: procgen(Chan *c, Dirtab *tab, int ntab, int s, Dir *dp)
        !            67: {
        !            68:        Qid qid;
        !            69:        Proc *p;
        !            70:        char buf[NAMELEN];
        !            71:        ulong pid, path, perm, len;
        !            72: 
        !            73:        USED(ntab);
        !            74:        if(c->qid.path == CHDIR){
        !            75:                if(s >= conf.nproc)
        !            76:                        return -1;
        !            77:                p = proctab(s);
        !            78:                pid = p->pid;
        !            79:                if(pid == 0)
        !            80:                        return 0;
        !            81:                sprint(buf, "%d", pid);
        !            82:                qid = (Qid){CHDIR|((s+1)<<QSHIFT), pid};
        !            83:                devdir(c, qid, buf, 0, p->user, CHDIR|0555, dp);
        !            84:                return 1;
        !            85:        }
        !            86:        if(s >= NPROC)
        !            87:                return -1;
        !            88:        if(tab)
        !            89:                panic("procgen");
        !            90: 
        !            91:        tab = &procdir[s];
        !            92:        path = c->qid.path&~(CHDIR|((1<<QSHIFT)-1));    /* slot component */
        !            93: 
        !            94:        p = proctab(SLOT(c->qid));
        !            95:        perm = tab->perm;
        !            96:        if(perm == 0)
        !            97:                perm = p->procmode;
        !            98: 
        !            99:        len = tab->length;
        !           100:        if(QID(c->qid) == Qwait)
        !           101:                len = p->nwait * sizeof(Waitmsg);
        !           102: 
        !           103:        qid = (Qid){path|tab->qid.path, c->qid.vers};
        !           104:        devdir(c, qid, tab->name, len, p->user, perm, dp);
        !           105:        return 1;
        !           106: }
        !           107: 
        !           108: void
        !           109: procinit(void)
        !           110: {
        !           111:        if(conf.nproc >= (1<<(16-QSHIFT))-1)
        !           112:                print("warning: too many procs for devproc\n");
        !           113: }
        !           114: 
        !           115: void
        !           116: procreset(void)
        !           117: {
        !           118: }
        !           119: 
        !           120: Chan*
        !           121: procattach(char *spec)
        !           122: {
        !           123:        return devattach('p', spec);
        !           124: }
        !           125: 
        !           126: Chan*
        !           127: procclone(Chan *c, Chan *nc)
        !           128: {
        !           129:        return devclone(c, nc);
        !           130: }
        !           131: 
        !           132: int
        !           133: procwalk(Chan *c, char *name)
        !           134: {
        !           135:        if(strcmp(name, "..") == 0) {
        !           136:                c->qid.path = Qdir|CHDIR;
        !           137:                return 1;
        !           138:        }
        !           139: 
        !           140:        return devwalk(c, name, 0, 0, procgen);
        !           141: }
        !           142: 
        !           143: void
        !           144: procstat(Chan *c, char *db)
        !           145: {
        !           146:        devstat(c, db, 0, 0, procgen);
        !           147: }
        !           148: 
        !           149: Chan *
        !           150: procopen(Chan *c, int omode)
        !           151: {
        !           152:        Proc *p;
        !           153:        Pgrp *pg;
        !           154:        Chan *tc;
        !           155: 
        !           156:        if(c->qid.path & CHDIR)
        !           157:                return devopen(c, omode, 0, 0, procgen);
        !           158: 
        !           159:        p = proctab(SLOT(c->qid));
        !           160:        pg = p->pgrp;
        !           161:        if(p->pid != PID(c->qid))
        !           162:                error(Eprocdied);
        !           163: 
        !           164:        omode = openmode(omode);
        !           165: 
        !           166:        switch(QID(c->qid)){
        !           167:        case Qtext:
        !           168:                tc = proctext(c, p);
        !           169:                tc->offset = 0;
        !           170:                return tc;
        !           171: 
        !           172:        case Qctl:
        !           173:        case Qnote:
        !           174:        case Qnoteid:
        !           175:        case Qmem:
        !           176:        case Qsegment:
        !           177:        case Qproc:
        !           178:        case Qstatus:
        !           179:        case Qwait:
        !           180:                break;
        !           181: 
        !           182:        case Qnotepg:
        !           183:                if(omode!=OWRITE || pg->pgrpid == 1)
        !           184:                        error(Eperm);
        !           185:                c->pgrpid.path = pg->pgrpid+1;
        !           186:                c->pgrpid.vers = p->noteid;
        !           187:                break;
        !           188: 
        !           189:        default:
        !           190:                pprint("procopen %lux\n", c->qid);
        !           191:                error(Egreg);
        !           192:        }
        !           193: 
        !           194:        /* Affix pid to qid */
        !           195:        if(p->state != Dead)
        !           196:                c->qid.vers = p->pid;
        !           197: 
        !           198:        return devopen(c, omode, 0, 0, procgen);
        !           199: }
        !           200: 
        !           201: void
        !           202: proccreate(Chan *c, char *name, int omode, ulong perm)
        !           203: {
        !           204:        USED(c, name, omode, perm);
        !           205:        error(Eperm);
        !           206: }
        !           207: 
        !           208: void
        !           209: procremove(Chan *c)
        !           210: {
        !           211:        USED(c);
        !           212:        error(Eperm);
        !           213: }
        !           214: 
        !           215: void
        !           216: procwstat(Chan *c, char *db)
        !           217: {
        !           218:        Proc *p;
        !           219:        Dir d;
        !           220: 
        !           221:        if(c->qid.path&CHDIR)
        !           222:                error(Eperm);
        !           223: 
        !           224:        convM2D(db, &d);
        !           225:        p = proctab(SLOT(c->qid));
        !           226:        if(p->pid != PID(c->qid))
        !           227:                error(Eprocdied);
        !           228: 
        !           229:        if(strcmp(u->p->user, p->user) != 0 && strcmp(u->p->user, eve) != 0)
        !           230:                error(Eperm);
        !           231: 
        !           232:        p->procmode = d.mode&0777;
        !           233: }
        !           234: 
        !           235: void
        !           236: procclose(Chan * c)
        !           237: {
        !           238:        USED(c);
        !           239: }
        !           240: 
        !           241: long
        !           242: procread(Chan *c, void *va, long n, ulong offset)
        !           243: {
        !           244:        Proc *p;
        !           245:        Page *pg;
        !           246:        KMap *k;
        !           247:        Segment *s;
        !           248:        int i, j;
        !           249:        long l;
        !           250:        User *up;
        !           251:        Segment *sg;
        !           252:        Waitq *wq;
        !           253:        char statbuf[NSEG*32];
        !           254:        char *a = va, *b, *sps;
        !           255: 
        !           256:        if(c->qid.path & CHDIR)
        !           257:                return devdirread(c, a, n, 0, 0, procgen);
        !           258: 
        !           259:        p = proctab(SLOT(c->qid));
        !           260:        if(p->pid != PID(c->qid))
        !           261:                error(Eprocdied);
        !           262: 
        !           263:        switch(QID(c->qid)){
        !           264:        case Qmem:
        !           265:                /* ugly math: USERADDR+BY2PG may be == 0 */
        !           266:                if(offset >= USERADDR && offset <= USERADDR+BY2PG-1) {
        !           267:                        if(offset+n >= USERADDR+BY2PG-1)
        !           268:                                n = USERADDR+BY2PG - offset;
        !           269:                        pg = p->upage;
        !           270:                        if(pg==0 || p->pid!=PID(c->qid))
        !           271:                                error(Eprocdied);
        !           272:                        k = kmap(pg);
        !           273:                        b = (char*)VA(k);
        !           274:                        memmove(a, b+(offset-USERADDR), n);
        !           275:                        kunmap(k);
        !           276:                        return n;
        !           277:                }
        !           278: 
        !           279:                if(offset >= KZERO) {
        !           280:                        /* Protect crypt key memory */
        !           281:                        if(offset < palloc.cmemtop && offset+n > palloc.cmembase)
        !           282:                                error(Eperm);
        !           283: 
        !           284:                        /* validate physical kernel addresses */
        !           285:                        if(offset < (ulong)end) {
        !           286:                                if(offset+n > (ulong)end)
        !           287:                                        n = (ulong)end - offset;
        !           288:                                memmove(a, (char*)offset, n);
        !           289:                                return n;
        !           290:                        }
        !           291:                        if(offset >= conf.base0 && offset < conf.npage0){
        !           292:                                if(offset+n > conf.npage0)
        !           293:                                        n = conf.npage0 - offset;
        !           294:                                memmove(a, (char*)offset, n);
        !           295:                                return n;
        !           296:                        }
        !           297:                        if(offset >= conf.base1 && offset < conf.npage1){
        !           298:                                if(offset+n > conf.npage1)
        !           299:                                        n = conf.npage1 - offset;
        !           300:                                memmove(a, (char*)offset, n);
        !           301:                                return n;
        !           302:                        }
        !           303:                }
        !           304: 
        !           305:                return procctlmemio(p, offset, n, va, 1);
        !           306: 
        !           307:        case Qnote:
        !           308:                qlock(&p->debug);
        !           309:                if(waserror()){
        !           310:                        qunlock(&p->debug);
        !           311:                        nexterror();
        !           312:                }
        !           313:                if(p->pid != PID(c->qid))
        !           314:                        error(Eprocdied);
        !           315:                k = kmap(p->upage);
        !           316:                up = (User*)VA(k);
        !           317:                if(up->p != p){
        !           318:                        kunmap(k);
        !           319:                        pprint("note read u/p mismatch");
        !           320:                        error(Egreg);
        !           321:                }
        !           322:                if(n < ERRLEN)
        !           323:                        error(Etoosmall);
        !           324:                if(up->nnote == 0)
        !           325:                        n = 0;
        !           326:                else{
        !           327:                        memmove(va, up->note[0].msg, ERRLEN);
        !           328:                        up->nnote--;
        !           329:                        memmove(&up->note[0], &up->note[1], up->nnote*sizeof(Note));
        !           330:                        n = ERRLEN;
        !           331:                }
        !           332:                if(up->nnote == 0)
        !           333:                        p->notepending = 0;
        !           334:                kunmap(k);
        !           335:                poperror();
        !           336:                qunlock(&p->debug);
        !           337:                return n;
        !           338: 
        !           339:        case Qproc:
        !           340:                if(offset >= sizeof(Proc))
        !           341:                        return 0;
        !           342:                if(offset+n > sizeof(Proc))
        !           343:                        n = sizeof(Proc) - offset;
        !           344:                memmove(a, ((char*)p)+offset, n);
        !           345:                return n;
        !           346: 
        !           347:        case Qstatus:
        !           348:                if(offset >= STATSIZE)
        !           349:                        return 0;
        !           350:                if(offset+n > STATSIZE)
        !           351:                        n = STATSIZE - offset;
        !           352: 
        !           353:                sps = p->psstate;
        !           354:                if(sps == 0)
        !           355:                        sps = statename[p->state];
        !           356:                memset(statbuf, ' ', sizeof statbuf);
        !           357:                memmove(statbuf+0*NAMELEN, p->text, strlen(p->text));
        !           358:                memmove(statbuf+1*NAMELEN, p->user, strlen(p->user));
        !           359:                memmove(statbuf+2*NAMELEN, sps, strlen(sps));
        !           360:                j = 2*NAMELEN + 12;
        !           361: 
        !           362:                for(i = 0; i < 6; i++) {
        !           363:                        l = p->time[i];
        !           364:                        if(i == TReal)
        !           365:                                l = MACHP(0)->ticks - l;
        !           366:                        l = TK2MS(l);
        !           367:                        readnum(0, statbuf+j+NUMSIZE*i, NUMSIZE, l, NUMSIZE);
        !           368:                }
        !           369:                /* ignore stack, which is mostly non-existent */
        !           370:                l = 0;
        !           371:                for(i=1; i<NSEG; i++){
        !           372:                        s = p->seg[i];
        !           373:                        if(s)
        !           374:                                l += s->top - s->base;
        !           375:                }
        !           376:                readnum(0, statbuf+j+NUMSIZE*6, NUMSIZE, l>>10, NUMSIZE);
        !           377:                memmove(a, statbuf+offset, n);
        !           378:                return n;
        !           379: 
        !           380:        case Qsegment:
        !           381:                j = 0;
        !           382:                for(i = 0; i < NSEG; i++)
        !           383:                        if(sg = p->seg[i])
        !           384:                                j += sprint(&statbuf[j], "%-6s %c %.8lux %.8lux %4d\n",
        !           385:                                sname[sg->type&SG_TYPE], sg->type&SG_RONLY ? 'R' : ' ',
        !           386:                                sg->base, sg->top, sg->ref);
        !           387:                if(offset >= j)
        !           388:                        return 0;
        !           389:                if(offset+n > j)
        !           390:                        n = j-offset;
        !           391:                if(n == 0 && offset == 0)
        !           392:                        exhausted("segments");
        !           393:                memmove(a, &statbuf[offset], n);
        !           394:                return n;
        !           395: 
        !           396:        case Qwait:
        !           397:                if(n < sizeof(Waitmsg))
        !           398:                        error(Etoosmall);
        !           399: 
        !           400:                if(!canqlock(&p->qwaitr))
        !           401:                        error(Einuse);
        !           402: 
        !           403:                if(waserror()) {
        !           404:                        qunlock(&p->qwaitr);
        !           405:                        nexterror();
        !           406:                }
        !           407: 
        !           408:                lock(&p->exl);
        !           409:                if(u->p == p && p->nchild == 0 && p->waitq == 0) {
        !           410:                        unlock(&p->exl);
        !           411:                        error(Enochild);
        !           412:                }
        !           413:                while(p->waitq == 0) {
        !           414:                        unlock(&p->exl);
        !           415:                        sleep(&p->waitr, haswaitq, p);
        !           416:                        lock(&p->exl);
        !           417:                }
        !           418:                wq = p->waitq;
        !           419:                p->waitq = wq->next;
        !           420:                p->nwait--;
        !           421:                unlock(&p->exl);
        !           422: 
        !           423:                qunlock(&p->qwaitr);
        !           424:                poperror();
        !           425:                memmove(a, &wq->w, sizeof(Waitmsg));
        !           426:                free(wq);
        !           427:                return sizeof(Waitmsg);
        !           428:        case Qnoteid:
        !           429:                return readnum(offset, va, n, p->noteid, NUMSIZE);
        !           430:        }
        !           431:        error(Egreg);
        !           432:        return 0;               /* not reached */
        !           433: }
        !           434: 
        !           435: 
        !           436: long
        !           437: procwrite(Chan *c, void *va, long n, ulong offset)
        !           438: {
        !           439:        int id;
        !           440:        User *up;
        !           441:        KMap *k;
        !           442:        Ureg *ur;
        !           443:        User *pxu;
        !           444:        Page *pg;
        !           445:        ulong hi;
        !           446:        char *a, *b;
        !           447:        char buf[ERRLEN];
        !           448:        Proc *p, *t, *et;
        !           449: 
        !           450:        if(c->qid.path & CHDIR)
        !           451:                error(Eisdir);
        !           452: 
        !           453:        a = va;
        !           454:        p = proctab(SLOT(c->qid));
        !           455: 
        !           456:        /* Use the remembered noteid in the channel
        !           457:         * rather than the process pgrpid
        !           458:         */
        !           459:        if(QID(c->qid) == Qnotepg) {
        !           460:                pgrpnote(NOTEID(c->pgrpid), va, n, NUser);
        !           461:                return n;
        !           462:        }
        !           463: 
        !           464:        qlock(&p->debug);
        !           465:        if(waserror()){
        !           466:                qunlock(&p->debug);
        !           467:                nexterror();
        !           468:        }
        !           469:        if(p->pid != PID(c->qid))
        !           470:                error(Eprocdied);
        !           471: 
        !           472:        switch(QID(c->qid)){
        !           473:        case Qmem:
        !           474:                if(p->state != Stopped)
        !           475:                        error(Ebadctl);
        !           476: 
        !           477:                if(offset >= USERADDR && offset <= USERADDR+BY2PG-1) {
        !           478:                        pg = p->upage;
        !           479:                        if(pg==0 || p->pid!=PID(c->qid))
        !           480:                                error(Eprocdied);
        !           481:                        k = kmap(pg);
        !           482:                        b = (char*)VA(k);
        !           483:                        pxu = (User*)b;
        !           484:                        hi = offset+n;
        !           485:                        /* Check for floating point registers */
        !           486:                        if(offset >= (ulong)&u->fpsave &&
        !           487:                           hi <= (ulong)&u->fpsave+sizeof(FPsave)){
        !           488:                                memmove(b+(offset-USERADDR), a, n);
        !           489:                                break;
        !           490:                        }
        !           491:                        /* Check user register set for process at kernel entry */
        !           492:                        ur = pxu->dbgreg;
        !           493:                        if(offset < (ulong)ur || hi > (ulong)ur+sizeof(Ureg)) {
        !           494:                                kunmap(k);
        !           495:                                error(Ebadarg);
        !           496:                        }
        !           497:                        ur = (Ureg*)(b+((ulong)ur-USERADDR));
        !           498:                        setregisters(ur, b+(offset-USERADDR), a, n);
        !           499:                        kunmap(k);
        !           500:                }
        !           501:                else    /* Try user memory segments */
        !           502:                        n = procctlmemio(p, offset, n, va, 0);
        !           503:                break;
        !           504: 
        !           505:        case Qctl:
        !           506:                procctlreq(p, va, n);
        !           507:                break;
        !           508: 
        !           509:        case Qnote:
        !           510:                if(p->kp)
        !           511:                        error(Eperm);
        !           512:                k = kmap(p->upage);
        !           513:                up = (User*)VA(k);
        !           514:                if(up->p != p){
        !           515:                        kunmap(k);
        !           516:                        pprint("note write u/p mismatch");
        !           517:                        error(Egreg);
        !           518:                }
        !           519:                kunmap(k);
        !           520:                if(n >= ERRLEN-1)
        !           521:                        error(Etoobig);
        !           522:                memmove(buf, va, n);
        !           523:                buf[n] = 0;
        !           524:                if(!postnote(p, 0, buf, NUser))
        !           525:                        error("note not posted");
        !           526:                break;
        !           527:        case Qnoteid:
        !           528:                id = atoi(a);
        !           529:                if(id == p->pid) {
        !           530:                        p->noteid = id;
        !           531:                        break;
        !           532:                }
        !           533:                t = proctab(0);
        !           534:                for(et = t+conf.nproc; t < et; t++) {
        !           535:                        if(id == t->noteid) {
        !           536:                                if(strcmp(p->user, t->user) != 0)
        !           537:                                        error(Eperm);
        !           538:                                p->noteid = id;
        !           539:                                break;
        !           540:                        }
        !           541:                }
        !           542:                if(p->noteid != id)
        !           543:                        error(Ebadarg);
        !           544:                break;
        !           545:        default:
        !           546:                pprint("unknown qid in procwrite\n");
        !           547:                error(Egreg);
        !           548:        }
        !           549:        poperror();
        !           550:        qunlock(&p->debug);
        !           551:        return n;
        !           552: }
        !           553: 
        !           554: Chan *
        !           555: proctext(Chan *c, Proc *p)
        !           556: {
        !           557:        Chan *tc;
        !           558:        Image *i;
        !           559:        Segment *s;
        !           560: 
        !           561:        s = p->seg[TSEG];
        !           562:        if(s == 0)
        !           563:                error(Enonexist);
        !           564:        if(p->state==Dead)
        !           565:                error(Eprocdied);
        !           566: 
        !           567:        lock(s);
        !           568:        i = s->image;
        !           569:        if(i == 0) {
        !           570:                unlock(s);
        !           571:                error(Eprocdied);
        !           572:        }
        !           573:        unlock(s);
        !           574: 
        !           575:        lock(i);
        !           576:        if(waserror()) {
        !           577:                unlock(i);
        !           578:                nexterror();
        !           579:        }
        !           580: 
        !           581:        tc = i->c;
        !           582:        if(tc == 0)
        !           583:                error(Eprocdied);
        !           584: 
        !           585:        if(incref(tc) == 1 || (tc->flag&COPEN) == 0 || tc->mode!=OREAD) {
        !           586:                close(tc);
        !           587:                error(Eprocdied);
        !           588:        }
        !           589: 
        !           590:        if(p->pid != PID(c->qid))
        !           591:                error(Eprocdied);
        !           592: 
        !           593:        unlock(i);
        !           594:        poperror();
        !           595: 
        !           596:        return tc;
        !           597: }
        !           598: 
        !           599: void
        !           600: procstopwait(Proc *p, int ctl)
        !           601: {
        !           602:        int pid;
        !           603: 
        !           604:        if(p->pdbg)
        !           605:                error(Einuse);
        !           606:        if(procstopped(p))
        !           607:                return;
        !           608: 
        !           609:        if(ctl != 0)
        !           610:                p->procctl = ctl;
        !           611:        p->pdbg = u->p;
        !           612:        pid = p->pid;
        !           613:        qunlock(&p->debug);
        !           614:        u->p->psstate = "Stopwait";
        !           615:        if(waserror()) {
        !           616:                p->pdbg = 0;
        !           617:                qlock(&p->debug);
        !           618:                nexterror();
        !           619:        }
        !           620:        sleep(&u->p->sleep, procstopped, p);
        !           621:        poperror();
        !           622:        qlock(&p->debug);
        !           623:        if(p->pid != pid)
        !           624:                error(Eprocdied);
        !           625: }
        !           626: 
        !           627: void
        !           628: procctlreq(Proc *p, char *va, int n)
        !           629: {
        !           630:        int i;
        !           631:        char buf[NAMELEN+1];
        !           632: 
        !           633:        if(n > NAMELEN)
        !           634:                n = NAMELEN;
        !           635:        strncpy(buf, va, n);
        !           636:        buf[NAMELEN] = '\0';
        !           637: 
        !           638:        if(strncmp(buf, "stop", 4) == 0)
        !           639:                procstopwait(p, Proc_stopme);
        !           640:        else if(strncmp(buf, "kill", 4) == 0) {
        !           641:                switch(p->state) {
        !           642:                case Broken:
        !           643:                        unbreak(p);
        !           644:                        break;
        !           645:                case Stopped:
        !           646:                        postnote(p, 0, "sys: killed", NExit);
        !           647:                        p->procctl = Proc_exitme;
        !           648:                        ready(p);
        !           649:                        break;
        !           650:                default:
        !           651:                        postnote(p, 0, "sys: killed", NExit);
        !           652:                        p->procctl = Proc_exitme;
        !           653:                }
        !           654:        }
        !           655:        else if(strncmp(buf, "hang", 4) == 0)
        !           656:                p->hang = 1;
        !           657:        else if(strncmp(buf, "nohang", 6) == 0)
        !           658:                p->hang = 0;
        !           659:        else if(strncmp(buf, "waitstop", 8) == 0)
        !           660:                procstopwait(p, 0);
        !           661:        else if(strncmp(buf, "startstop", 9) == 0) {
        !           662:                if(p->state != Stopped)
        !           663:                        error(Ebadctl);
        !           664:                p->procctl = Proc_traceme;
        !           665:                ready(p);
        !           666:                procstopwait(p, Proc_traceme);
        !           667:        }
        !           668:        else if(strncmp(buf, "start", 5) == 0) {
        !           669:                if(p->state != Stopped)
        !           670:                        error(Ebadctl);
        !           671:                ready(p);
        !           672:        }
        !           673:        else if(strncmp(buf, "pri", 3) == 0){
        !           674:                if(n < 4)
        !           675:                        error(Ebadctl);
        !           676:                i = atoi(buf+4);
        !           677:                if(i < 0)
        !           678:                        i = 0;
        !           679:                if(i >= Nrq)
        !           680:                        i = Nrq - 1;
        !           681:                if(i < p->basepri && !iseve())
        !           682:                        error(Eperm);
        !           683:                p->basepri = i;
        !           684:        }
        !           685:        else
        !           686:                error(Ebadctl);
        !           687: }
        !           688: 
        !           689: int
        !           690: procstopped(void *a)
        !           691: {
        !           692:        Proc *p = a;
        !           693:        return p->state == Stopped;
        !           694: }
        !           695: 
        !           696: int
        !           697: procctlmemio(Proc *p, ulong offset, int n, void *va, int read)
        !           698: {
        !           699:        KMap *k;
        !           700:        Pte *pte;
        !           701:        Page *pg;
        !           702:        Segment *s;
        !           703:        ulong soff, l;
        !           704:        char *a = va, *b;
        !           705: 
        !           706:        for(;;) {
        !           707:                s = seg(p, offset, 1);
        !           708:                if(s == 0)
        !           709:                        error(Ebadarg);
        !           710: 
        !           711:                if(offset+n >= s->top)
        !           712:                        n = s->top-offset;
        !           713: 
        !           714:                if(read == 0 && (s->type&SG_TYPE) == SG_TEXT)
        !           715:                        s = txt2data(p, s);
        !           716: 
        !           717:                s->steal++;
        !           718:                soff = offset-s->base;
        !           719:                if(waserror()) {
        !           720:                        s->steal--;
        !           721:                        nexterror();
        !           722:                }
        !           723:                if(fixfault(s, offset, read, 0) == 0)
        !           724:                        break;
        !           725:                poperror();
        !           726:                s->steal--;
        !           727:        }
        !           728:        poperror();
        !           729:        pte = s->map[soff/PTEMAPMEM];
        !           730:        if(pte == 0)
        !           731:                panic("procctlmemio"); 
        !           732:        pg = pte->pages[(soff&(PTEMAPMEM-1))/BY2PG];
        !           733:        if(pagedout(pg))
        !           734:                panic("procctlmemio1"); 
        !           735: 
        !           736:        l = BY2PG - (offset&(BY2PG-1));
        !           737:        if(n > l)
        !           738:                n = l;
        !           739: 
        !           740:        k = kmap(pg);
        !           741:        b = (char*)VA(k);
        !           742:        if(read == 1)
        !           743:                memmove(a, b+(offset&(BY2PG-1)), n);
        !           744:        else
        !           745:                memmove(b+(offset&(BY2PG-1)), a, n);
        !           746: 
        !           747:        kunmap(k);
        !           748: 
        !           749:        s->steal--;
        !           750:        qunlock(&s->lk);
        !           751: 
        !           752:        if(read == 0)
        !           753:                p->newtlb = 1;
        !           754: 
        !           755:        return n;
        !           756: }
        !           757: 
        !           758: Segment*
        !           759: txt2data(Proc *p, Segment *s)
        !           760: {
        !           761:        int i;
        !           762:        Segment *ps;
        !           763: 
        !           764:        ps = newseg(SG_DATA, s->base, s->size);
        !           765:        ps->image = s->image;
        !           766:        incref(ps->image);
        !           767:        ps->fstart = s->fstart;
        !           768:        ps->flen = s->flen;
        !           769:        ps->flushme = 1;
        !           770: 
        !           771:        for(i = 0; i < NSEG; i++)
        !           772:                if(p->seg[i] == s)
        !           773:                        break;
        !           774:        if(p->seg[i] != s)
        !           775:                panic("segment gone");
        !           776: 
        !           777:        qunlock(&s->lk);
        !           778:        putseg(s);
        !           779:        qlock(&ps->lk);
        !           780:        p->seg[i] = ps;
        !           781: 
        !           782:        return ps;
        !           783: }
        !           784: 
        !           785: Segment*
        !           786: data2txt(Segment *s)
        !           787: {
        !           788:        Segment *ps;
        !           789: 
        !           790:        ps = newseg(SG_TEXT, s->base, s->size);
        !           791:        ps->image = s->image;
        !           792:        incref(ps->image);
        !           793:        ps->fstart = s->fstart;
        !           794:        ps->flen = s->flen;
        !           795:        ps->flushme = 1;
        !           796: 
        !           797:        return ps;
        !           798: }

unix.superglobalmegacorp.com

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