Annotation of lucent/sys/src/9/port/devcons.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       "io.h"
        !             7: #include       "../port/error.h"
        !             8: 
        !             9: #include       "devtab.h"
        !            10: 
        !            11: struct {
        !            12:        IOQ;                    /* lock to klogputs */
        !            13:        QLock;                  /* qlock to getc */
        !            14: }klogq;
        !            15: 
        !            16: IOQ    mouseq;
        !            17: IOQ    lineq;                  /* lock to getc; interrupt putc's */
        !            18: IOQ    printq;
        !            19: KIOQ   kbdq;
        !            20: 
        !            21: static Ref     ctl;            /* number of opens to the control file */
        !            22: static int     raw;            /* true if raw has been requested on ctl file */
        !            23: 
        !            24: char   sysname[NAMELEN];
        !            25: 
        !            26: /*
        !            27:  *  init the queues and set the output routine
        !            28:  */
        !            29: void
        !            30: printinit(void)
        !            31: {
        !            32:        initq(&printq);
        !            33:        printq.puts = 0;
        !            34:        initq(&lineq);
        !            35:        initq(&kbdq);
        !            36:        kbdq.putc = kbdputc;
        !            37:        initq(&klogq);
        !            38:        initq(&mouseq);
        !            39:        mouseq.putc = mouseputc;
        !            40: }
        !            41: 
        !            42: /*
        !            43:  *   Print a string on the console.  Convert \n to \r\n for serial
        !            44:  *   line consoles.  Locking of the queues is left up to the screen
        !            45:  *   or uart code.  Multi-line messages to serial consoles may get
        !            46:  *   interspersed with other messages.
        !            47:  */
        !            48: void
        !            49: putstrn(char *str, int n)
        !            50: {
        !            51:        char buf[PRINTSIZE+2];
        !            52:        int m;
        !            53:        char *t;
        !            54: 
        !            55:        /*
        !            56:         *  if there's an attached bit mapped display,
        !            57:         *  put the message there.  screenputs is defined
        !            58:         *  as a null macro for systems that have no such
        !            59:         *  display.
        !            60:         */
        !            61:        screenputs(str, n);
        !            62: 
        !            63:        /*
        !            64:         *  if there's a serial line being used as a console,
        !            65:         *  put the message there.  Tack a carriage return
        !            66:         *  before new lines.
        !            67:         */
        !            68:        if(printq.puts == 0)
        !            69:                return;
        !            70: 
        !            71:        while(n > 0){
        !            72:                t = memchr(str, '\n', n);
        !            73:                if(t){
        !            74:                        m = t - str;
        !            75:                        memmove(buf, str, m);
        !            76:                        buf[m] = '\r';
        !            77:                        buf[m+1] = '\n';
        !            78:                        (*printq.puts)(&printq, buf, m+2);
        !            79:                        str = t + 1;
        !            80:                        n -= m + 1;
        !            81:                } else {
        !            82:                        (*printq.puts)(&printq, str, n);
        !            83:                        break;
        !            84:                }
        !            85:        }
        !            86: }
        !            87: 
        !            88: /*
        !            89:  *   Print a string in the kernel log.  Ignore overflow.
        !            90:  */
        !            91: void
        !            92: klogputs(char *str, long n)
        !            93: {
        !            94:        int s, m;
        !            95:        uchar *nextin;
        !            96: 
        !            97:        s = splhi();
        !            98:        lock(&klogq);
        !            99:        while(n){
        !           100:                m = &klogq.buf[NQ] - klogq.in;
        !           101:                if(m > n)
        !           102:                        m = n;
        !           103:                memmove(klogq.in, str, m);
        !           104:                n -= m;
        !           105:                str += m;
        !           106:                nextin = klogq.in + m;
        !           107:                if(nextin >= &klogq.buf[NQ])
        !           108:                        klogq.in = klogq.buf;
        !           109:                else
        !           110:                        klogq.in = nextin;
        !           111:        }
        !           112:        unlock(&klogq);
        !           113:        splx(s);
        !           114:        wakeup(&klogq.r);
        !           115: }
        !           116: 
        !           117: int
        !           118: isbrkc(KIOQ *q)
        !           119: {
        !           120:        uchar *p;
        !           121: 
        !           122:        for(p=q->out; p!=q->in; ){
        !           123:                if(raw)
        !           124:                        return 1;
        !           125:                if(*p==0x04 || *p=='\n')
        !           126:                        return 1;
        !           127:                p++;
        !           128:                if(p >= q->buf+sizeof(q->buf))
        !           129:                        p = q->buf;
        !           130:        }
        !           131:        return 0;
        !           132: }
        !           133: 
        !           134: int
        !           135: sprint(char *s, char *fmt, ...)
        !           136: {
        !           137:        return doprint(s, s+PRINTSIZE, fmt, (&fmt+1)) - s;
        !           138: }
        !           139: 
        !           140: int
        !           141: snprint(char *s, int n, char *fmt, ...)
        !           142: {
        !           143:        return doprint(s, s+n, fmt, (&fmt+1)) - s;
        !           144: }
        !           145: 
        !           146: int
        !           147: print(char *fmt, ...)
        !           148: {
        !           149:        char buf[PRINTSIZE];
        !           150:        int n;
        !           151: 
        !           152:        n = doprint(buf, buf+sizeof(buf), fmt, (&fmt+1)) - buf;
        !           153:        putstrn(buf, n);
        !           154:        return n;
        !           155: }
        !           156: 
        !           157: int
        !           158: kprint(char *fmt, ...)
        !           159: {
        !           160:        char buf[PRINTSIZE];
        !           161:        int n;
        !           162: 
        !           163:        n = doprint(buf, buf+sizeof(buf), fmt, (&fmt+1)) - buf;
        !           164:        klogputs(buf, n);
        !           165:        return n;
        !           166: }
        !           167: 
        !           168: void
        !           169: panic(char *fmt, ...)
        !           170: {
        !           171:        char buf[PRINTSIZE];
        !           172:        int n;
        !           173: 
        !           174:        strcpy(buf, "panic: ");
        !           175:        n = doprint(buf+strlen(buf), buf+sizeof(buf), fmt, (&fmt+1)) - buf;
        !           176:        buf[n] = '\n';
        !           177:        putstrn(buf, n+1);
        !           178:        dumpstack();
        !           179:        exit(1);
        !           180: }
        !           181: int
        !           182: pprint(char *fmt, ...)
        !           183: {
        !           184:        char buf[2*PRINTSIZE];
        !           185:        Chan *c;
        !           186:        int n;
        !           187: 
        !           188:        if(u->p->fgrp == 0)
        !           189:                return 0;
        !           190: 
        !           191:        c = u->p->fgrp->fd[2];
        !           192:        if(c==0 || (c->mode!=OWRITE && c->mode!=ORDWR))
        !           193:                return 0;
        !           194:        n = sprint(buf, "%s %d: ", u->p->text, u->p->pid);
        !           195:        n = doprint(buf+n, buf+sizeof(buf), fmt, (&fmt+1)) - buf;
        !           196: 
        !           197:        if(waserror())
        !           198:                return 0;
        !           199:        (*devtab[c->type].write)(c, buf, n, c->offset);
        !           200:        poperror();
        !           201: 
        !           202:        lock(c);
        !           203:        c->offset += n;
        !           204:        unlock(c);
        !           205: 
        !           206:        return n;
        !           207: }
        !           208: 
        !           209: void
        !           210: prflush(void)
        !           211: {
        !           212:        while(printq.in != printq.out) ;
        !           213: }
        !           214: #include <ureg.h>
        !           215: void
        !           216: echo(Rune r, char *buf, int n)
        !           217: {
        !           218:        static int ctrlt;
        !           219: 
        !           220:        /*
        !           221:         * ^p hack
        !           222:         */
        !           223:        if(r==0x10 && cpuserver)
        !           224:                exit(0);
        !           225: 
        !           226:        /*
        !           227:         * ^t hack BUG
        !           228:         */
        !           229:        if(ctrlt == 2){
        !           230:                ctrlt = 0;
        !           231:                switch(r){
        !           232:                case 0x14:
        !           233:                        break;  /* pass it on */
        !           234:                case 'x':
        !           235:                        xsummary();
        !           236:                        break;
        !           237:                case 'b':
        !           238:                        bitdebug();
        !           239:                        break;
        !           240:                case 'd':
        !           241:                        consdebug();
        !           242:                        return;
        !           243:                case 'p':
        !           244:                        procdump();
        !           245:                        return;
        !           246:                case 'r':
        !           247:                        exit(0);
        !           248:                        break;
        !           249:                }
        !           250:        }else if(r == 0x14){
        !           251:                ctrlt++;
        !           252:                return;
        !           253:        }
        !           254:        ctrlt = 0;
        !           255:        if(raw)
        !           256:                return;
        !           257:        if(r == 0x15)
        !           258:                putstrn("^U\n", 3);
        !           259:        else
        !           260:                putstrn(buf, n);
        !           261: }
        !           262: 
        !           263: /*
        !           264:  *  turn '\r' into '\n' before putting it into the queue
        !           265:  */
        !           266: int
        !           267: kbdcr2nl(IOQ *q, int ch)
        !           268: {
        !           269:        if(ch == '\r')
        !           270:                ch = '\n';
        !           271:        return kbdputc(q, ch);
        !           272: }
        !           273: 
        !           274: /*
        !           275:  *  Put character, possibly a rune, into read queue at interrupt time.
        !           276:  *  Always called splhi from processor 0.
        !           277:  */
        !           278: int
        !           279: kbdputc(IOQ *q, int ch)
        !           280: {
        !           281:        int i, n;
        !           282:        char buf[3];
        !           283:        Rune r;
        !           284: 
        !           285:        USED(q);
        !           286:        r = ch;
        !           287:        n = runetochar(buf, &r);
        !           288:        if(n == 0)
        !           289:                return 0;
        !           290:        echo(r, buf, n);
        !           291:        kbdq.c = r;
        !           292:        for(i=0; i<n; i++){
        !           293:                *kbdq.in++ = buf[i];
        !           294:                if(kbdq.in == kbdq.buf+sizeof(kbdq.buf))
        !           295:                        kbdq.in = kbdq.buf;
        !           296:        }
        !           297:        if(raw || r=='\n' || r==0x04)
        !           298:                wakeup(&kbdq.r);
        !           299:        return 0;
        !           300: }
        !           301: 
        !           302: void
        !           303: kbdrepeat(int rep)
        !           304: {
        !           305:        kbdq.repeat = rep;
        !           306:        kbdq.count = 0;
        !           307: }
        !           308: 
        !           309: void
        !           310: kbdclock(void)
        !           311: {
        !           312:        if(kbdq.repeat == 0)
        !           313:                return;
        !           314:        if(kbdq.repeat==1 && ++kbdq.count>HZ){
        !           315:                kbdq.repeat = 2;
        !           316:                kbdq.count = 0;
        !           317:                return;
        !           318:        }
        !           319:        if(++kbdq.count&1)
        !           320:                kbdputc(&kbdq, kbdq.c);
        !           321: }
        !           322: 
        !           323: int
        !           324: consactive(void)
        !           325: {
        !           326:        return printq.in != printq.out;
        !           327: }
        !           328: 
        !           329: enum{
        !           330:        Qdir,
        !           331:        Qauth,
        !           332:        Qauthcheck,
        !           333:        Qauthent,
        !           334:        Qclock,
        !           335:        Qcons,
        !           336:        Qconsctl,
        !           337:        Qcputime,
        !           338:        Qhz,
        !           339:        Qkey,
        !           340:        Qhostdomain,
        !           341:        Qhostowner,
        !           342:        Qklog,
        !           343:        Qlights,
        !           344:        Qmsec,
        !           345:        Qnoise,
        !           346:        Qnull,
        !           347:        Qpgrpid,
        !           348:        Qpid,
        !           349:        Qppid,
        !           350:        Qswap,
        !           351:        Qsysname,
        !           352:        Qsysstat,
        !           353:        Qtime,
        !           354:        Quser,
        !           355: };
        !           356: 
        !           357: Dirtab consdir[]={
        !           358:        "authenticate", {Qauth},        0,              0666,
        !           359:        "authcheck",    {Qauthcheck},   0,              0666,
        !           360:        "authenticator", {Qauthent},    0,              0666,
        !           361:        "clock",        {Qclock},       2*NUMSIZE,      0444,
        !           362:        "cons",         {Qcons},        0,              0660,
        !           363:        "consctl",      {Qconsctl},     0,              0220,
        !           364:        "cputime",      {Qcputime},     6*NUMSIZE,      0444,
        !           365:        "hostdomain",   {Qhostdomain},  DOMLEN,         0664,
        !           366:        "hostowner",    {Qhostowner},   NAMELEN,        0664,
        !           367:        "hz",           {Qhz},          NUMSIZE,        0666,
        !           368:        "key",          {Qkey},         DESKEYLEN,      0622,
        !           369:        "klog",         {Qklog},        0,              0444,
        !           370:        "lights",       {Qlights},      0,              0220,
        !           371:        "msec",         {Qmsec},        NUMSIZE,        0444,
        !           372:        "noise",        {Qnoise},       0,              0220,
        !           373:        "null",         {Qnull},        0,              0666,
        !           374:        "pgrpid",       {Qpgrpid},      NUMSIZE,        0444,
        !           375:        "pid",          {Qpid},         NUMSIZE,        0444,
        !           376:        "ppid",         {Qppid},        NUMSIZE,        0444,
        !           377:        "swap",         {Qswap},        0,              0664,
        !           378:        "sysname",      {Qsysname},     0,              0664,
        !           379:        "sysstat",      {Qsysstat},     0,              0666,
        !           380:        "time",         {Qtime},        NUMSIZE,        0664,
        !           381:        "user",         {Quser},        NAMELEN,        0666,
        !           382: };
        !           383: 
        !           384: #define        NCONS   (sizeof consdir/sizeof(Dirtab))
        !           385: 
        !           386: ulong  boottime;               /* seconds since epoch at boot */
        !           387: 
        !           388: long
        !           389: seconds(void)
        !           390: {
        !           391:        return boottime + TK2SEC(MACHP(0)->ticks);
        !           392: }
        !           393: 
        !           394: int
        !           395: readnum(ulong off, char *buf, ulong n, ulong val, int size)
        !           396: {
        !           397:        char tmp[64];
        !           398:        Fconv fconv = (Fconv){ tmp, tmp+sizeof(tmp), size-1, 0, 0, 'u' };
        !           399: 
        !           400:        numbconv(&val, &fconv);
        !           401:        tmp[size-1] = ' ';
        !           402:        if(off >= size)
        !           403:                return 0;
        !           404:        if(off+n > size)
        !           405:                n = size-off;
        !           406:        memmove(buf, tmp+off, n);
        !           407:        return n;
        !           408: }
        !           409: 
        !           410: int
        !           411: readstr(ulong off, char *buf, ulong n, char *str)
        !           412: {
        !           413:        int size;
        !           414: 
        !           415:        size = strlen(str);
        !           416:        if(off >= size)
        !           417:                return 0;
        !           418:        if(off+n > size)
        !           419:                n = size-off;
        !           420:        memmove(buf, str+off, n);
        !           421:        return n;
        !           422: }
        !           423: 
        !           424: void
        !           425: consreset(void)
        !           426: {
        !           427: }
        !           428: 
        !           429: void
        !           430: consinit(void)
        !           431: {
        !           432: }
        !           433: 
        !           434: Chan*
        !           435: consattach(char *spec)
        !           436: {
        !           437:        return devattach('c', spec);
        !           438: }
        !           439: 
        !           440: Chan*
        !           441: consclone(Chan *c, Chan *nc)
        !           442: {
        !           443:        return devclone(c, nc);
        !           444: }
        !           445: 
        !           446: int
        !           447: conswalk(Chan *c, char *name)
        !           448: {
        !           449:        return devwalk(c, name, consdir, NCONS, devgen);
        !           450: }
        !           451: 
        !           452: void
        !           453: consstat(Chan *c, char *dp)
        !           454: {
        !           455:        devstat(c, dp, consdir, NCONS, devgen);
        !           456: }
        !           457: 
        !           458: Chan*
        !           459: consopen(Chan *c, int omode)
        !           460: {
        !           461:        c->aux = 0;
        !           462:        switch(c->qid.path){
        !           463:        case Qconsctl:
        !           464:                if(!iseve())
        !           465:                        error(Eperm);
        !           466:                incref(&ctl);
        !           467:                break;
        !           468:        }
        !           469:        return devopen(c, omode, consdir, NCONS, devgen);
        !           470: }
        !           471: 
        !           472: void
        !           473: conscreate(Chan *c, char *name, int omode, ulong perm)
        !           474: {
        !           475:        USED(c, name, omode, perm);
        !           476:        error(Eperm);
        !           477: }
        !           478: 
        !           479: void
        !           480: consclose(Chan *c)
        !           481: {
        !           482:        /* last close of control file turns off raw */
        !           483:        switch(c->qid.path){
        !           484:        case Qconsctl:
        !           485:                if(c->flag&COPEN){
        !           486:                        lock(&ctl);
        !           487:                        if(--ctl.ref == 0)
        !           488:                                raw = 0;
        !           489:                        unlock(&ctl);
        !           490:                }
        !           491:                break;
        !           492:        case Qauth:
        !           493:        case Qauthcheck:
        !           494:        case Qauthent:
        !           495:                authclose(c);
        !           496:                break;
        !           497:        }
        !           498: }
        !           499: 
        !           500: long
        !           501: consread(Chan *c, void *buf, long n, ulong offset)
        !           502: {
        !           503:        int ch, i, k, id;
        !           504:        ulong l;
        !           505:        char *cbuf = buf;
        !           506:        char *b, *bp;
        !           507:        char tmp[128];  /* must be >= 6*NUMSIZE */
        !           508:        Mach *mp;
        !           509: 
        !           510:        if(n <= 0)
        !           511:                return n;
        !           512:        switch(c->qid.path & ~CHDIR){
        !           513:        case Qdir:
        !           514:                return devdirread(c, buf, n, consdir, NCONS, devgen);
        !           515: 
        !           516:        case Qcons:
        !           517:                qlock(&kbdq);
        !           518:                if(waserror()){
        !           519:                        qunlock(&kbdq);
        !           520:                        nexterror();
        !           521:                }
        !           522:                while(!cangetc(&lineq)){
        !           523:                        sleep(&kbdq.r, isbrkc, &kbdq);
        !           524:                        do{
        !           525:                                lock(&lineq);
        !           526:                                ch = getc(&kbdq);
        !           527:                                if(raw)
        !           528:                                        goto Default;
        !           529:                                switch(ch){
        !           530:                                case '\b':
        !           531:                                        if(lineq.in != lineq.out){
        !           532:                                                if(lineq.in == lineq.buf)
        !           533:                                                        lineq.in = lineq.buf+sizeof(lineq.buf);
        !           534:                                                lineq.in--;
        !           535:                                        }
        !           536:                                        break;
        !           537:                                case 0x15:
        !           538:                                        lineq.in = lineq.out;
        !           539:                                        break;
        !           540:                                Default:
        !           541:                                default:
        !           542:                                        *lineq.in = ch;
        !           543:                                        if(lineq.in >= lineq.buf+sizeof(lineq.buf)-1)
        !           544:                                                lineq.in = lineq.buf;
        !           545:                                        else
        !           546:                                                lineq.in++;
        !           547:                                }
        !           548:                                unlock(&lineq);
        !           549:                        }while(raw==0 && ch!='\n' && ch!=0x04);
        !           550:                }
        !           551:                i = 0;
        !           552:                while(n > 0){
        !           553:                        ch = getc(&lineq);
        !           554:                        if(ch==-1 || (raw==0 && ch==0x04))
        !           555:                                break;
        !           556:                        i++;
        !           557:                        *cbuf++ = ch;
        !           558:                        --n;
        !           559:                }
        !           560:                poperror();
        !           561:                qunlock(&kbdq);
        !           562:                return i;
        !           563: 
        !           564:        case Qcputime:
        !           565:                k = offset;
        !           566:                if(k >= 6*NUMSIZE)
        !           567:                        return 0;
        !           568:                if(k+n > 6*NUMSIZE)
        !           569:                        n = 6*NUMSIZE - k;
        !           570:                /* easiest to format in a separate buffer and copy out */
        !           571:                for(i=0; i<6 && NUMSIZE*i<k+n; i++){
        !           572:                        l = u->p->time[i];
        !           573:                        if(i == TReal)
        !           574:                                l = MACHP(0)->ticks - l;
        !           575:                        l = TK2MS(l);
        !           576:                        readnum(0, tmp+NUMSIZE*i, NUMSIZE, l, NUMSIZE);
        !           577:                }
        !           578:                memmove(buf, tmp+k, n);
        !           579:                return n;
        !           580: 
        !           581:        case Qpgrpid:
        !           582:                return readnum(offset, buf, n, u->p->pgrp->pgrpid, NUMSIZE);
        !           583: 
        !           584:        case Qpid:
        !           585:                return readnum(offset, buf, n, u->p->pid, NUMSIZE);
        !           586: 
        !           587:        case Qppid:
        !           588:                return readnum(offset, buf, n, u->p->parentpid, NUMSIZE);
        !           589: 
        !           590:        case Qtime:
        !           591:                return readnum(offset, buf, n, boottime+TK2SEC(MACHP(0)->ticks), 12);
        !           592: 
        !           593:        case Qclock:
        !           594:                k = offset;
        !           595:                if(k >= 2*NUMSIZE)
        !           596:                        return 0;
        !           597:                if(k+n > 2*NUMSIZE)
        !           598:                        n = 2*NUMSIZE - k;
        !           599:                readnum(0, tmp, NUMSIZE, MACHP(0)->ticks, NUMSIZE);
        !           600:                readnum(0, tmp+NUMSIZE, NUMSIZE, HZ, NUMSIZE);
        !           601:                memmove(buf, tmp+k, n);
        !           602:                return n;
        !           603: 
        !           604:        case Qkey:
        !           605:                return keyread(buf, n, offset);
        !           606: 
        !           607:        case Qauth:
        !           608:                return authread(c, cbuf, n);
        !           609: 
        !           610:        case Qauthent:
        !           611:                return authentread(c, cbuf, n);
        !           612: 
        !           613:        case Qhostowner:
        !           614:                return readstr(offset, buf, n, eve);
        !           615: 
        !           616:        case Qhostdomain:
        !           617:                return readstr(offset, buf, n, hostdomain);
        !           618: 
        !           619:        case Quser:
        !           620:                return readstr(offset, buf, n, u->p->user);
        !           621: 
        !           622:        case Qnull:
        !           623:                return 0;
        !           624: 
        !           625:        case Qklog:
        !           626:                qlock(&klogq);
        !           627:                if(waserror()){
        !           628:                        qunlock(&klogq);
        !           629:                        nexterror();
        !           630:                }
        !           631:                while(!cangetc(&klogq))
        !           632:                        sleep(&klogq.r, cangetc, &klogq);
        !           633:                for(i=0; i<n; i++){
        !           634:                        if((ch=getc(&klogq)) == -1)
        !           635:                                break;
        !           636:                        *cbuf++ = ch;
        !           637:                }
        !           638:                poperror();
        !           639:                qunlock(&klogq);
        !           640:                return i;
        !           641: 
        !           642:        case Qmsec:
        !           643:                return readnum(offset, buf, n, TK2MS(MACHP(0)->ticks), NUMSIZE);
        !           644: 
        !           645:        case Qhz:
        !           646:                return readnum(offset, buf, n, HZ, NUMSIZE);
        !           647: 
        !           648:        case Qsysstat:
        !           649:                b = smalloc(conf.nmach*(NUMSIZE*8+1) + 1);      /* +1 for NUL */
        !           650:                bp = b;
        !           651:                for(id = 0; id < 32; id++) {
        !           652:                        if(active.machs & (1<<id)) {
        !           653:                                mp = MACHP(id);
        !           654:                                readnum(0, bp, NUMSIZE, id, NUMSIZE);
        !           655:                                bp += NUMSIZE;
        !           656:                                readnum(0, bp, NUMSIZE, mp->cs, NUMSIZE);
        !           657:                                bp += NUMSIZE;
        !           658:                                readnum(0, bp, NUMSIZE, mp->intr, NUMSIZE);
        !           659:                                bp += NUMSIZE;
        !           660:                                readnum(0, bp, NUMSIZE, mp->syscall, NUMSIZE);
        !           661:                                bp += NUMSIZE;
        !           662:                                readnum(0, bp, NUMSIZE, mp->pfault, NUMSIZE);
        !           663:                                bp += NUMSIZE;
        !           664:                                readnum(0, bp, NUMSIZE, mp->tlbfault, NUMSIZE);
        !           665:                                bp += NUMSIZE;
        !           666:                                readnum(0, bp, NUMSIZE, mp->tlbpurge, NUMSIZE);
        !           667:                                bp += NUMSIZE;
        !           668:                                readnum(0, bp, NUMSIZE, mp->load, NUMSIZE);
        !           669:                                bp += NUMSIZE;
        !           670:                                *bp++ = '\n';
        !           671:                        }
        !           672:                }
        !           673:                n = readstr(offset, buf, n, b);
        !           674:                free(b);
        !           675:                return n;
        !           676: 
        !           677:        case Qswap:
        !           678:                sprint(tmp, "%d/%d memory %d/%d swap\n",
        !           679:                                palloc.user-palloc.freecount, palloc.user, 
        !           680:                                conf.nswap-swapalloc.free, conf.nswap);
        !           681: 
        !           682:                return readstr(offset, buf, n, tmp);
        !           683: 
        !           684:        case Qsysname:
        !           685:                return readstr(offset, buf, n, sysname);
        !           686: 
        !           687:        default:
        !           688:                print("consread %lux\n", c->qid);
        !           689:                error(Egreg);
        !           690:        }
        !           691:        return -1;              /* never reached */
        !           692: }
        !           693: 
        !           694: void
        !           695: conslights(char *a, int n)
        !           696: {
        !           697:        char line[128];
        !           698:        char *lp;
        !           699:        int c;
        !           700: 
        !           701:        lp = line;
        !           702:        while(n--){
        !           703:                *lp++ = c = *a++;
        !           704:                if(c=='\n' || n==0 || lp==&line[sizeof(line)-1])
        !           705:                        break;
        !           706:        }
        !           707:        *lp = 0;
        !           708:        lights(strtoul(line, 0, 0));
        !           709: }
        !           710: 
        !           711: void
        !           712: consnoise(char *a, int n)
        !           713: {
        !           714:        int freq;
        !           715:        int duration;
        !           716:        char line[128];
        !           717:        char *lp;
        !           718:        int c;
        !           719: 
        !           720:        lp = line;
        !           721:        while(n--){
        !           722:                *lp++ = c = *a++;
        !           723:                if(c=='\n' || n==0 || lp==&line[sizeof(line)-1]){
        !           724:                        *lp = 0;
        !           725:                        freq = strtoul(line, &lp, 0);
        !           726:                        while(*lp==' ' || *lp=='\t')
        !           727:                                lp++;
        !           728:                        duration = strtoul(lp, &lp, 0);
        !           729:                        buzz(freq, duration);
        !           730:                        lp = line;
        !           731:                }
        !           732:        }
        !           733: }
        !           734: 
        !           735: long
        !           736: conswrite(Chan *c, void *va, long n, ulong offset)
        !           737: {
        !           738:        char cbuf[64];
        !           739:        char buf[256];
        !           740:        long l, bp;
        !           741:        char *a = va;
        !           742:        Mach *mp;
        !           743:        int id, fd, ch;
        !           744:        Chan *swc;
        !           745: 
        !           746:        switch(c->qid.path){
        !           747:        case Qcons:
        !           748:                l = n;
        !           749:                while(l > 0){
        !           750:                        bp = l;
        !           751:                        if(bp > sizeof buf)
        !           752:                                bp = sizeof buf;
        !           753:                        memmove(buf, a, bp);
        !           754:                        putstrn(a, bp);
        !           755:                        a += bp;
        !           756:                        l -= bp;
        !           757:                }
        !           758:                break;
        !           759: 
        !           760:        case Qconsctl:
        !           761:                if(n >= sizeof(buf))
        !           762:                        n = sizeof(buf)-1;
        !           763:                strncpy(buf, a, n);
        !           764:                buf[n] = 0;
        !           765:                if(strncmp(a, "rawon", 5) == 0){
        !           766:                        lock(&lineq);
        !           767:                        while((ch=getc(&kbdq)) != -1){
        !           768:                                *lineq.in++ = ch;
        !           769:                                if(lineq.in == lineq.buf+sizeof(lineq.buf))
        !           770:                                        lineq.in = lineq.buf;
        !           771:                        }
        !           772:                        unlock(&lineq);
        !           773:                        lock(&ctl);
        !           774:                        raw = 1;
        !           775:                        unlock(&ctl);
        !           776:                } 
        !           777:                else
        !           778:                if(strncmp(a, "rawoff", 6) == 0){
        !           779:                        lock(&ctl);
        !           780:                        raw = 0;
        !           781:                        unlock(&ctl);
        !           782:                }
        !           783:                else
        !           784:                        error(Ebadctl);
        !           785:                break;
        !           786: 
        !           787:        case Qtime:
        !           788:                if(n<=0 || boottime!=0) /* write once file */
        !           789:                        return 0;
        !           790:                if(n >= sizeof cbuf)
        !           791:                        n = sizeof cbuf - 1;
        !           792:                memmove(cbuf, a, n);
        !           793:                cbuf[n-1] = 0;
        !           794:                boottime = strtoul(a, 0, 0)-TK2SEC(MACHP(0)->ticks);
        !           795:                break;
        !           796: 
        !           797:        case Qkey:
        !           798:                return keywrite(a, n);
        !           799: 
        !           800:        case Qhostowner:
        !           801:                return hostownerwrite(a, n);
        !           802: 
        !           803:        case Qhostdomain:
        !           804:                return hostdomainwrite(a, n);
        !           805: 
        !           806:        case Quser:
        !           807:                return userwrite(a, n);
        !           808: 
        !           809:        case Qauth:
        !           810:                return authwrite(c, a, n);
        !           811: 
        !           812:        case Qauthcheck:
        !           813:                return authcheck(c, a, n);
        !           814: 
        !           815:        case Qauthent:
        !           816:                return authentwrite(c, a, n);
        !           817: 
        !           818:        case Qnull:
        !           819:                break;
        !           820: 
        !           821:        case Qnoise:
        !           822:                consnoise(a, n);
        !           823:                break;
        !           824: 
        !           825:        case Qlights:
        !           826:                conslights(a, n);
        !           827:                break;
        !           828: 
        !           829:        case Qsysstat:
        !           830:                for(id = 0; id < 32; id++) {
        !           831:                        if(active.machs & (1<<id)) {
        !           832:                                mp = MACHP(id);
        !           833:                                mp->cs = 0;
        !           834:                                mp->intr = 0;
        !           835:                                mp->syscall = 0;
        !           836:                                mp->pfault = 0;
        !           837:                                mp->tlbfault = 0;
        !           838:                                mp->tlbpurge = 0;
        !           839:                        }
        !           840:                }
        !           841:                break;
        !           842: 
        !           843:        case Qswap:
        !           844:                if(n >= sizeof buf)
        !           845:                        error(Egreg);
        !           846:                memmove(buf, va, n);    /* so we can NUL-terminate */
        !           847:                buf[n] = 0;
        !           848:                /* start a pager if not already started */
        !           849:                if(strncmp(buf, "start", 5) == 0){
        !           850:                        kickpager();
        !           851:                        break;
        !           852:                }
        !           853:                if(cpuserver && strcmp(u->p->user, eve) != 0)
        !           854:                        error(Eperm);
        !           855:                if(buf[0]<'0' || '9'<buf[0])
        !           856:                        error(Ebadusefd);
        !           857:                fd = strtoul(buf, 0, 0);
        !           858:                swc = fdtochan(fd, -1, 1, 0);
        !           859:                setswapchan(swc);
        !           860:                break;
        !           861: 
        !           862:        case Qsysname:
        !           863:                if(offset != 0)
        !           864:                        error(Ebadarg);
        !           865:                if(n <= 0 || n >= NAMELEN)
        !           866:                        error(Ebadarg);
        !           867:                strncpy(sysname, a, n);
        !           868:                sysname[n] = 0;
        !           869:                if(sysname[n-1] == '\n')
        !           870:                        sysname[n-1] = 0;
        !           871:                break;
        !           872: 
        !           873:        default:
        !           874:                print("conswrite: %d\n", c->qid.path);
        !           875:                error(Egreg);
        !           876:        }
        !           877:        return n;
        !           878: }
        !           879: 
        !           880: void
        !           881: consremove(Chan *c)
        !           882: {
        !           883:        USED(c);
        !           884:        error(Eperm);
        !           885: }
        !           886: 
        !           887: void
        !           888: conswstat(Chan *c, char *dp)
        !           889: {
        !           890:        USED(c, dp);
        !           891:        error(Eperm);
        !           892: }
        !           893: 
        !           894: int
        !           895: nrand(int n)
        !           896: {
        !           897:        static ulong randn;
        !           898: 
        !           899:        randn = randn*1103515245 + 12345 + MACHP(0)->ticks;
        !           900:        return (randn>>16) % n;
        !           901: }
        !           902: 
        !           903: void
        !           904: setterm(char *f)
        !           905: {
        !           906:        char buf[2*NAMELEN];
        !           907: 
        !           908:        sprint(buf, f, conffile);
        !           909:        ksetenv("terminal", buf);
        !           910: }

unix.superglobalmegacorp.com

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