Annotation of 43BSDReno/sys/kern/subr_prf.c, revision 1.1.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.