Annotation of 43BSDReno/sys/kern/subr_prf.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1982, 1986, 1988 Regents of the University of California.
        !             3:  * All rights reserved.  The Berkeley software License Agreement
        !             4:  * specifies the terms and conditions for redistribution.
        !             5:  *
        !             6:  *     @(#)subr_prf.c  7.18 (Berkeley) 6/28/90
        !             7:  */
        !             8: 
        !             9: #include "param.h"
        !            10: #include "systm.h"
        !            11: #include "seg.h"
        !            12: #include "buf.h"
        !            13: #include "conf.h"
        !            14: #include "reboot.h"
        !            15: #include "vm.h"
        !            16: #include "msgbuf.h"
        !            17: #include "user.h"
        !            18: #include "proc.h"
        !            19: #include "ioctl.h"
        !            20: #include "vnode.h"
        !            21: #include "file.h"
        !            22: #include "tty.h"
        !            23: #include "tprintf.h"
        !            24: #include "syslog.h"
        !            25: #include "malloc.h"
        !            26: 
        !            27: #include "machine/mtpr.h"
        !            28: #ifdef KADB
        !            29: #include "machine/kdbparam.h"
        !            30: #endif
        !            31: 
        !            32: #define TOCONS 0x1
        !            33: #define TOTTY  0x2
        !            34: #define TOLOG  0x4
        !            35: 
        !            36: /*
        !            37:  * In case console is off,
        !            38:  * panicstr contains argument to last
        !            39:  * call to panic.
        !            40:  */
        !            41: char   *panicstr;
        !            42: 
        !            43: extern cnputc();                       /* standard console putc */
        !            44: int    (*v_putc)() = cnputc;           /* routine to putc on virtual console */
        !            45: extern struct tty cons;                /* standard console tty */
        !            46: struct tty *constty;                   /* pointer to console "window" tty */
        !            47: 
        !            48: #ifdef KADB
        !            49: extern cngetc();                       /* standard console getc */
        !            50: extern cnpoll();
        !            51: int    (*v_getc)() = cngetc;           /* "" getc from virtual console */
        !            52: int    (*v_poll)() = cnpoll;           /* kdb hook to enable input polling */
        !            53: #endif
        !            54: 
        !            55: /*
        !            56:  * Scaled down version of C Library printf.
        !            57:  * Used to print diagnostic information directly on console tty.
        !            58:  * Since it is not interrupt driven, all system activities are
        !            59:  * suspended.  Printf should not be used for chit-chat.
        !            60:  *
        !            61:  * One additional format: %b is supported to decode error registers.
        !            62:  * Usage is:
        !            63:  *     printf("reg=%b\n", regval, "<base><arg>*");
        !            64:  * Where <base> is the output base expressed as a control character,
        !            65:  * e.g. \10 gives octal; \20 gives hex.  Each arg is a sequence of
        !            66:  * characters, the first of which gives the bit number to be inspected
        !            67:  * (origin 1), and the next characters (up to a control character, i.e.
        !            68:  * a character <= 32), give the name of the register.  Thus
        !            69:  *     printf("reg=%b\n", 3, "\10\2BITTWO\1BITONE\n");
        !            70:  * would produce output:
        !            71:  *     reg=3<BITTWO,BITONE>
        !            72:  *
        !            73:  * Another additional format: %r is used to pass an additional format string
        !            74:  * and argument list recursively.  Usage is typically:
        !            75:  *
        !            76:  * fn(otherstuff, fmt [, arg1, ... ] )
        !            77:  *     char *fmt;
        !            78:  *     u_int arg1, ...;
        !            79:  *
        !            80:  *     printf("prefix: %r, other stuff\n", fmt, &arg1);
        !            81:  */
        !            82: #if defined(tahoe)
        !            83: int    consintr;
        !            84: #endif
        !            85: 
        !            86: /*VARARGS1*/
        !            87: printf(fmt, x1)
        !            88:        char *fmt;
        !            89:        unsigned x1;
        !            90: {
        !            91: #if defined(tahoe)
        !            92:        register int savintr;
        !            93: 
        !            94:        savintr = consintr, consintr = 0;       /* disable interrupts */
        !            95: #endif
        !            96:        prf(fmt, &x1, TOCONS | TOLOG, (struct tty *)NULL);
        !            97:        if (!panicstr)
        !            98:                logwakeup();
        !            99: #if defined(tahoe)
        !           100:        consintr = savintr;                     /* reenable interrupts */
        !           101: #endif
        !           102: }
        !           103: 
        !           104: /*
        !           105:  * Uprintf prints to the controlling terminal for the current process.
        !           106:  * It may block if the tty queue is overfull.
        !           107:  * No message is printed if the queue does not clear
        !           108:  * in a reasonable time.
        !           109:  */
        !           110: /*VARARGS1*/
        !           111: uprintf(fmt, x1)
        !           112:        char *fmt;
        !           113:        unsigned x1;
        !           114: {
        !           115:        register struct proc *p = u.u_procp;
        !           116: 
        !           117:        if (p->p_flag & SCTTY && p->p_session->s_ttyvp)
        !           118:                prf(fmt, &x1, TOTTY, p->p_session->s_ttyp);
        !           119: }
        !           120: 
        !           121: tpr_t
        !           122: tprintf_open()
        !           123: {
        !           124:        register struct proc *p = u.u_procp;
        !           125: 
        !           126:        if (p->p_flag & SCTTY && p->p_session->s_ttyvp) {
        !           127:                SESSHOLD(p->p_session);
        !           128:                return ((tpr_t)p->p_session);
        !           129:        } else
        !           130:                return ((tpr_t)NULL);
        !           131: }
        !           132: 
        !           133: tprintf_close(sess)
        !           134:        tpr_t sess;
        !           135: {
        !           136:        if (sess)
        !           137:                SESSRELE(sess);
        !           138: }
        !           139: 
        !           140: /*
        !           141:  * tprintf prints on the controlling terminal associated
        !           142:  * with the given session.  
        !           143:  */
        !           144: /*VARARGS2*/
        !           145: tprintf(sess, fmt, x1)
        !           146:        register tpr_t sess;
        !           147:        char *fmt;
        !           148:        unsigned x1;
        !           149: {
        !           150:        int flags = TOLOG;
        !           151: 
        !           152:        logpri(LOG_INFO);
        !           153: 
        !           154:        if (sess && sess->s_ttyvp && ttycheckoutq(sess->s_ttyp, 0))
        !           155:                flags |= TOTTY;
        !           156:        prf(fmt, &x1, flags, sess->s_ttyp);
        !           157:        logwakeup();
        !           158: }
        !           159: 
        !           160: 
        !           161: /*
        !           162:  * Log writes to the log buffer,
        !           163:  * and guarantees not to sleep (so can be called by interrupt routines).
        !           164:  * If there is no process reading the log yet, it writes to the console also.
        !           165:  */
        !           166: /*VARARGS2*/
        !           167: log(level, fmt, x1)
        !           168:        char *fmt;
        !           169:        unsigned x1;
        !           170: {
        !           171:        register s = splhigh();
        !           172:        extern int log_open;
        !           173: 
        !           174:        logpri(level);
        !           175:        prf(fmt, &x1, TOLOG, (struct tty *)NULL);
        !           176:        splx(s);
        !           177:        if (!log_open)
        !           178:                prf(fmt, &x1, TOCONS, (struct tty *)NULL);
        !           179:        logwakeup();
        !           180: }
        !           181: 
        !           182: logpri(level)
        !           183:        int level;
        !           184: {
        !           185: 
        !           186:        putchar('<', TOLOG, (struct tty *)NULL);
        !           187:        printn((u_long)level, 10, TOLOG, (struct tty *)NULL);
        !           188:        putchar('>', TOLOG, (struct tty *)NULL);
        !           189: }
        !           190: 
        !           191: /*VARARGS1*/
        !           192: addlog(fmt, x1)
        !           193:        char *fmt;
        !           194:        unsigned x1;
        !           195: {
        !           196:        register s = splhigh();
        !           197: 
        !           198:        prf(fmt, &x1, TOLOG, (struct tty *)NULL);
        !           199:        splx(s);
        !           200:        if (!log_open)
        !           201:                prf(fmt, &x1, TOCONS, (struct tty *)NULL);
        !           202:        logwakeup();
        !           203: }
        !           204: 
        !           205: prf(fmt, adx, flags, ttyp)
        !           206:        register char *fmt;
        !           207:        register u_int *adx;
        !           208:        struct tty *ttyp;
        !           209: {
        !           210:        register int b, c, i;
        !           211:        char *s;
        !           212:        int any;
        !           213: 
        !           214: loop:
        !           215:        while ((c = *fmt++) != '%') {
        !           216:                if (c == '\0')
        !           217:                        return;
        !           218:                putchar(c, flags, ttyp);
        !           219:        }
        !           220: again:
        !           221:        c = *fmt++;
        !           222:        /* THIS CODE IS MACHINE DEPENDENT IN HANDLING %l? AND %c */
        !           223:        switch (c) {
        !           224: 
        !           225:        case 'l':
        !           226:                goto again;
        !           227:        case 'x': case 'X':
        !           228:                b = 16;
        !           229:                goto number;
        !           230:        case 'd': case 'D':
        !           231:                b = -10;
        !           232:                goto number;
        !           233:        case 'u':
        !           234:                b = 10;
        !           235:                goto number;
        !           236:        case 'o': case 'O':
        !           237:                b = 8;
        !           238: number:
        !           239:                printn((u_long)*adx, b, flags, ttyp);
        !           240:                break;
        !           241:        case 'c':
        !           242:                b = *adx;
        !           243: #if BYTE_ORDER == LITTLE_ENDIAN
        !           244:                for (i = 24; i >= 0; i -= 8)
        !           245:                        if (c = (b >> i) & 0x7f)
        !           246:                                putchar(c, flags, ttyp);
        !           247: #endif
        !           248: #if BYTE_ORDER == BIG_ENDIAN
        !           249:                if (c = (b & 0x7f))
        !           250:                        putchar(c, flags, ttyp);
        !           251: #endif
        !           252:                break;
        !           253:        case 'b':
        !           254:                b = *adx++;
        !           255:                s = (char *)*adx;
        !           256:                printn((u_long)b, *s++, flags, ttyp);
        !           257:                any = 0;
        !           258:                if (b) {
        !           259:                        while (i = *s++) {
        !           260:                                if (b & (1 << (i-1))) {
        !           261:                                        putchar(any ? ',' : '<', flags, ttyp);
        !           262:                                        any = 1;
        !           263:                                        for (; (c = *s) > 32; s++)
        !           264:                                                putchar(c, flags, ttyp);
        !           265:                                } else
        !           266:                                        for (; *s > 32; s++)
        !           267:                                                ;
        !           268:                        }
        !           269:                        if (any)
        !           270:                                putchar('>', flags, ttyp);
        !           271:                }
        !           272:                break;
        !           273: 
        !           274:        case 's':
        !           275:                s = (char *)*adx;
        !           276:                while (c = *s++)
        !           277:                        putchar(c, flags, ttyp);
        !           278:                break;
        !           279: 
        !           280:        case 'r':
        !           281:                s = (char *)*adx++;
        !           282:                prf(s, (u_int *)*adx, flags, ttyp);
        !           283:                break;
        !           284: 
        !           285:        case '%':
        !           286:                putchar('%', flags, ttyp);
        !           287:                break;
        !           288:        }
        !           289:        adx++;
        !           290:        goto loop;
        !           291: }
        !           292: 
        !           293: /*
        !           294:  * Printn prints a number n in base b.
        !           295:  * We don't use recursion to avoid deep kernel stacks.
        !           296:  */
        !           297: printn(n, b, flags, ttyp)
        !           298:        u_long n;
        !           299:        struct tty *ttyp;
        !           300: {
        !           301:        char prbuf[11];
        !           302:        register char *cp;
        !           303: 
        !           304:        if (b == -10) {
        !           305:                if ((int)n < 0) {
        !           306:                        putchar('-', flags, ttyp);
        !           307:                        n = (unsigned)(-(int)n);
        !           308:                }
        !           309:                b = -b;
        !           310:        }
        !           311:        cp = prbuf;
        !           312:        do {
        !           313:                *cp++ = "0123456789abcdef"[n%b];
        !           314:                n /= b;
        !           315:        } while (n);
        !           316:        do
        !           317:                putchar(*--cp, flags, ttyp);
        !           318:        while (cp > prbuf);
        !           319: }
        !           320: 
        !           321: /*
        !           322:  * Panic is called on unresolvable fatal errors.
        !           323:  * It prints "panic: mesg", and then reboots.
        !           324:  * If we are called twice, then we avoid trying to
        !           325:  * sync the disks as this often leads to recursive panics.
        !           326:  */
        !           327: panic(s)
        !           328:        char *s;
        !           329: {
        !           330:        int bootopt = RB_AUTOBOOT | RB_DUMP;
        !           331: 
        !           332:        if (panicstr)
        !           333:                bootopt |= RB_NOSYNC;
        !           334:        else {
        !           335:                panicstr = s;
        !           336:        }
        !           337:        printf("panic: %s\n", s);
        !           338: #ifdef KADB
        !           339:        if (boothowto & RB_KDB) {
        !           340:                int x = splnet();       /* below kdb pri */
        !           341: 
        !           342:                setsoftkdb();
        !           343:                splx(x);
        !           344:        }
        !           345: #endif
        !           346:        boot(bootopt);
        !           347: }
        !           348: 
        !           349: /*
        !           350:  * Warn that a system table is full.
        !           351:  */
        !           352: tablefull(tab)
        !           353:        char *tab;
        !           354: {
        !           355: 
        !           356:        log(LOG_ERR, "%s: table is full\n", tab);
        !           357: }
        !           358: 
        !           359: /*
        !           360:  * Print a character on console or users terminal.
        !           361:  * If destination is console then the last MSGBUFS characters
        !           362:  * are saved in msgbuf for inspection later.
        !           363:  */
        !           364: /*ARGSUSED*/
        !           365: putchar(c, flags, ttyp)
        !           366:        register int c;
        !           367:        struct tty *ttyp;
        !           368: {
        !           369:        extern int msgbufmapped;
        !           370: 
        !           371:        if (panicstr)
        !           372:                constty = 0;
        !           373:        if ((flags & TOCONS) && ttyp == NULL && constty) {
        !           374:                ttyp = constty;
        !           375:                flags |= TOTTY;
        !           376:        }
        !           377:        if ((flags & TOTTY) && ttyp && tputchar(c, ttyp) < 0 &&
        !           378:            (flags & TOCONS) && ttyp == constty)
        !           379:                constty = 0;
        !           380:        if ((flags & TOLOG) && c != '\0' && c != '\r' && c != 0177 &&
        !           381:            msgbufmapped) {
        !           382:                if (msgbuf.msg_magic != MSG_MAGIC) {
        !           383:                        register int i;
        !           384: 
        !           385:                        msgbuf.msg_magic = MSG_MAGIC;
        !           386:                        msgbuf.msg_bufx = msgbuf.msg_bufr = 0;
        !           387:                        for (i=0; i < MSG_BSIZE; i++)
        !           388:                                msgbuf.msg_bufc[i] = 0;
        !           389:                }
        !           390:                msgbuf.msg_bufc[msgbuf.msg_bufx++] = c;
        !           391:                if (msgbuf.msg_bufx < 0 || msgbuf.msg_bufx >= MSG_BSIZE)
        !           392:                        msgbuf.msg_bufx = 0;
        !           393:        }
        !           394:        if ((flags & TOCONS) && constty == 0 && c != '\0')
        !           395:                (*v_putc)(c);
        !           396: }

unix.superglobalmegacorp.com

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