1: /*
   2:  * Copyright (c) 1986 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	1.2 (2.11BSD) 1998/12/5
   7:  */
   8: 
   9: #include "param.h"
  10: #include "user.h"
  11: #include "machine/seg.h"
  12: #include "buf.h"
  13: #include "msgbuf.h"
  14: #include "conf.h"
  15: #include "ioctl.h"
  16: #include "tty.h"
  17: #include "reboot.h"
  18: #include "systm.h"
  19: #include "syslog.h"
  20: 
  21: #define TOCONS  0x1
  22: #define TOTTY   0x2
  23: #define TOLOG   0x4
  24: 
  25: /*
  26:  * In case console is off,
  27:  * panicstr contains argument to last
  28:  * call to panic.
  29:  */
  30: char    *panicstr;
  31: 
  32: /*
  33:  * Scaled down version of C Library printf.
  34:  * Used to print diagnostic information directly on console tty.
  35:  * Since it is not interrupt driven, all system activities are
  36:  * suspended.  Printf should not be used for chit-chat.
  37:  *
  38:  * One additional format: %b is supported to decode error registers.
  39:  * Usage is:
  40:  *	printf("reg=%b\n", regval, "<base><arg>*");
  41:  * Where <base> is the output base expressed as a control character,
  42:  * e.g. \10 gives octal; \20 gives hex.  Each arg is a sequence of
  43:  * characters, the first of which gives the bit number to be inspected
  44:  * (origin 1), and the next characters (up to a control character, i.e.
  45:  * a character <= 32), give the name of the register.  Thus
  46:  *	printf("reg=%b\n", 3, "\10\2BITTWO\1BITONE\n");
  47:  * would produce output:
  48:  *	reg=3<BITTWO,BITONE>
  49:  */
  50: 
  51: /*VARARGS1*/
  52: printf(fmt, x1)
  53:     char *fmt;
  54:     unsigned x1;
  55: {
  56:     prf(fmt, &x1, TOCONS | TOLOG, (struct tty *)0);
  57: }
  58: 
  59: /*
  60:  * Uprintf prints to the current user's terminal,
  61:  * guarantees not to sleep (so could be called by interrupt routines;
  62:  * but prints on the tty of the current process)
  63:  * and does no watermark checking - (so no verbose messages).
  64:  * NOTE: with current kernel mapping scheme, the user structure is
  65:  * not guaranteed to be accessible at interrupt level (see seg.h);
  66:  * a savemap/restormap would be needed here or in putchar if uprintf
  67:  * was to be used at interrupt time.
  68:  */
  69: /*VARARGS1*/
  70: uprintf(fmt, x1)
  71:     char    *fmt;
  72:     unsigned x1;
  73: {
  74:     register struct tty *tp;
  75: 
  76:     if ((tp = u.u_ttyp) == NULL)
  77:         return;
  78: 
  79:     if (ttycheckoutq(tp, 1))
  80:         prf(fmt, &x1, TOTTY, tp);
  81: }
  82: 
  83: /*
  84:  * tprintf prints on the specified terminal (console if none)
  85:  * and logs the message.  It is designed for error messages from
  86:  * single-open devices, and may be called from interrupt level
  87:  * (does not sleep).
  88:  */
  89: /*VARARGS2*/
  90: tprintf(tp, fmt, x1)
  91:     register struct tty *tp;
  92:     char *fmt;
  93:     unsigned x1;
  94: {
  95:     int flags = TOTTY | TOLOG;
  96:     extern struct tty cons;
  97: 
  98:     logpri(LOG_INFO);
  99:     if (tp == (struct tty *)NULL)
 100:         tp = &cons;
 101:     if (ttycheckoutq(tp, 0) == 0)
 102:         flags = TOLOG;
 103:     prf(fmt, &x1, flags, tp);
 104:     logwakeup(logMSG);
 105: }
 106: 
 107: /*
 108:  * Log writes to the log buffer,
 109:  * and guarantees not to sleep (so can be called by interrupt routines).
 110:  * If there is no process reading the log yet, it writes to the console also.
 111:  */
 112: /*VARARGS2*/
 113: log(level, fmt, x1)
 114:     char *fmt;
 115:     unsigned x1;
 116: {
 117:     register s = splhigh();
 118: 
 119:     logpri(level);
 120:     prf(fmt, &x1, TOLOG, (struct tty *)0);
 121:     splx(s);
 122:     if (!logisopen(logMSG))
 123:         prf(fmt, &x1, TOCONS, (struct tty *)0);
 124:     logwakeup(logMSG);
 125: }
 126: 
 127: logpri(level)
 128:     int level;
 129: {
 130: 
 131:     putchar('<', TOLOG, (struct tty *)0);
 132:     printn((u_long)level, 10, TOLOG, (struct tty *)0);
 133:     putchar('>', TOLOG, (struct tty *)0);
 134: }
 135: 
 136: prf(fmt, adx, flags, ttyp)
 137:     register char *fmt;
 138:     register u_int *adx;
 139:     int flags;
 140:     struct tty *ttyp;
 141: {
 142:     register int c;
 143:     u_int b;
 144:     char *s;
 145:     int i, any;
 146: 
 147: loop:
 148:     while ((c = *fmt++) != '%') {
 149:         if (c == '\0')
 150:             return;
 151:         putchar(c, flags, ttyp);
 152:     }
 153:     c = *fmt++;
 154:     switch (c) {
 155: 
 156:     case 'l':
 157:         c = *fmt++;
 158:         switch(c) {
 159:             case 'x':
 160:                 b = 16;
 161:                 goto lnumber;
 162:             case 'd':
 163:                 b = 10;
 164:                 goto lnumber;
 165:             case 'o':
 166:                 b = 8;
 167:                 goto lnumber;
 168:             default:
 169:                 putchar('%', flags, ttyp);
 170:                 putchar('l', flags, ttyp);
 171:                 putchar(c, flags, ttyp);
 172:         }
 173:         break;
 174:     case 'X':
 175:         b = 16;
 176:         goto lnumber;
 177:     case 'D':
 178:         b = 10;
 179:         goto lnumber;
 180:     case 'O':
 181:         b = 8;
 182: lnumber:    printn(*(long *)adx, b, flags, ttyp);
 183:         adx += (sizeof(long) / sizeof(int)) - 1;
 184:         break;
 185:     case 'x':
 186:         b = 16;
 187:         goto number;
 188:     case 'd':
 189:     case 'u':       /* what a joke */
 190:         b = 10;
 191:         goto number;
 192:     case 'o':
 193:         b = 8;
 194: number:     printn((long)*adx, b, flags, ttyp);
 195:         break;
 196:     case 'c':
 197:         putchar(*adx, flags, ttyp);
 198:         break;
 199:     case 'b':
 200:         b = *adx++;
 201:         s = (char *)*adx;
 202:         printn((long)b, *s++, flags, ttyp);
 203:         any = 0;
 204:         if (b) {
 205:             while (i = *s++) {
 206:                 if (b & (1 << (i - 1))) {
 207:                     putchar(any? ',' : '<', flags, ttyp);
 208:                     any = 1;
 209:                     for (; (c = *s) > 32; s++)
 210:                         putchar(c, flags, ttyp);
 211:                 } else
 212:                     for (; *s > 32; s++)
 213:                         ;
 214:             }
 215:             if (any)
 216:                 putchar('>', flags, ttyp);
 217:         }
 218:         break;
 219:     case 's':
 220:         s = (char *)*adx;
 221:         while (c = *s++)
 222:             putchar(c, flags, ttyp);
 223:         break;
 224:     case '%':
 225:         putchar(c, flags, ttyp);
 226:         break;
 227:     default:
 228:         putchar('%', flags, ttyp);
 229:         putchar(c, flags, ttyp);
 230:         break;
 231:     }
 232:     adx++;
 233:     goto loop;
 234: }
 235: 
 236: /*
 237:  * Printn prints a number n in base b.
 238:  * We don't use recursion to avoid deep kernels stacks.
 239:  */
 240: printn(n, b, flags, ttyp)
 241:     long n;
 242:     u_int b;
 243:     struct tty *ttyp;
 244: {
 245:     char prbuf[12];
 246:     register char *cp = prbuf;
 247:     register int offset = 0;
 248: 
 249:     if (n<0)
 250:         switch(b) {
 251:         case 8:     /* unchecked, but should be like hex case */
 252:         case 16:
 253:             offset = b-1;
 254:             n++;
 255:             break;
 256:         case 10:
 257:             putchar('-', flags, ttyp);
 258:             n = -n;
 259:             break;
 260:         }
 261:     do {
 262:         *cp++ = "0123456789ABCDEF"[offset + n%b];
 263:     } while (n = n/b);  /* Avoid  n /= b, since that requires alrem */
 264:     do
 265:         putchar(*--cp, flags, ttyp);
 266:     while (cp > prbuf);
 267: }
 268: 
 269: /*
 270:  * Panic is called on unresolvable fatal errors.
 271:  * It prints "panic: mesg", and then reboots.
 272:  * If we are called twice, then we avoid trying to
 273:  * sync the disks as this often leads to recursive panics.
 274:  */
 275: panic(s)
 276:     char *s;
 277: {
 278:     int bootopt = RB_AUTOBOOT|RB_DUMP;
 279: 
 280:     if (panicstr)
 281:         bootopt |= RB_NOSYNC;
 282:     else {
 283:         panicstr = s;
 284:     }
 285:     printf("panic: %s\n", s);
 286:     boot(rootdev, bootopt);
 287: }
 288: 
 289: /*
 290:  * Warn that a system table is full.
 291:  */
 292: tablefull(tab)
 293:     char *tab;
 294: {
 295:     log(LOG_ERR, "%s: table full\n", tab);
 296: }
 297: 
 298: /*
 299:  * Hard error is the preface to plaintive error messages
 300:  * about failing disk tranfers.
 301:  */
 302: harderr(bp, cp)
 303:     struct buf *bp;
 304:     char *cp;
 305: {
 306:     printf("%s%d%c: hard error sn%D ", cp,
 307:         minor(bp->b_dev) >> 3, 'a'+(minor(bp->b_dev) & 07), bp->b_blkno);
 308: }
 309: 
 310: /*
 311:  * Print a character on console or users terminal.
 312:  * If destination is console then the last MSGBUFS characters
 313:  * are saved in msgbuf for inspection later.
 314:  */
 315: putchar(c, flags, tp)
 316:     int c, flags;
 317:     register struct tty *tp;
 318: {
 319: 
 320:     if (flags & TOTTY) {
 321:         register int s = spltty();
 322: 
 323:         if (tp && (tp->t_state & (TS_CARR_ON | TS_ISOPEN)) ==
 324:             (TS_CARR_ON | TS_ISOPEN)) {
 325:             if (c == '\n')
 326:                 (void) ttyoutput('\r', tp);
 327:             (void) ttyoutput(c, tp);
 328:             ttstart(tp);
 329:         }
 330:         splx(s);
 331:     }
 332:     if ((flags & TOLOG) && c != '\0' && c != '\r' && c != 0177)
 333:         logwrt(&c, 1, logMSG);
 334:     if ((flags & TOCONS) && c != '\0')
 335:         cnputc(c);
 336: }

Defined functions

logpri defined in line 127; used 2 times
panic defined in line 275; used 137 times
prf defined in line 136; used 5 times
printf defined in line 52; used 296 times
printn defined in line 240; used 4 times
putchar defined in line 315; used 18 times
tprintf defined in line 90; used 8 times

Defined variables

panicstr defined in line 30; used 2 times

Defined macros

TOCONS defined in line 21; used 3 times
TOLOG defined in line 23; used 8 times
TOTTY defined in line 22; used 3 times
Last modified: 1998-12-06
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 4136
Valid CSS Valid XHTML 1.0 Strict