X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/68503f9a0ca5129190c66647aa8f618b5cc5d441..7bf304e65beb1e282cd098ed53ab9f4999b78280:/usr/src/sys/kern/subr_prf.c diff --git a/usr/src/sys/kern/subr_prf.c b/usr/src/sys/kern/subr_prf.c index c7d1cc9b28..b2e04feebe 100644 --- a/usr/src/sys/kern/subr_prf.c +++ b/usr/src/sys/kern/subr_prf.c @@ -1,17 +1,33 @@ -/* subr_prf.c 4.21 82/01/16 */ - -#include "../h/param.h" -#include "../h/systm.h" -#include "../h/seg.h" -#include "../h/buf.h" -#include "../h/conf.h" -#include "../h/mtpr.h" -#include "../h/reboot.h" -#include "../h/vm.h" -#include "../h/msgbuf.h" -#include "../h/dir.h" -#include "../h/user.h" -#include "../h/tty.h" +/* + * Copyright (c) 1982, 1986, 1988 Regents of the University of California. + * All rights reserved. The Berkeley software License Agreement + * specifies the terms and conditions for redistribution. + * + * @(#)subr_prf.c 7.14 (Berkeley) %G% + */ + +#include "param.h" +#include "systm.h" +#include "seg.h" +#include "buf.h" +#include "conf.h" +#include "reboot.h" +#include "vm.h" +#include "msgbuf.h" +#include "user.h" +#include "proc.h" +#include "ioctl.h" +#include "tty.h" +#include "syslog.h" + +#include "machine/mtpr.h" +#ifdef KADB +#include "machine/kdbparam.h" +#endif + +#define TOCONS 0x1 +#define TOTTY 0x2 +#define TOLOG 0x4 /* * In case console is off, @@ -20,6 +36,16 @@ */ char *panicstr; +extern cnputc(); /* standard console putc */ +extern struct tty cons; /* standard console tty */ +struct tty *constty; /* pointer to console "window" tty */ +int (*v_putc)() = cnputc; /* routine to putc on virtual console */ + +extern cnputc(); /* standard console putc */ +extern struct tty cons; /* standard console tty */ +struct tty *constty; /* pointer to console "window" tty */ +int (*v_console)() = cnputc; /* routine to putc on virtual console */ + /* * Scaled down version of C Library printf. * Used to print diagnostic information directly on console tty. @@ -36,34 +62,141 @@ char *panicstr; * a character <= 32), give the name of the register. Thus * printf("reg=%b\n", 3, "\10\2BITTWO\1BITONE\n"); * would produce output: - * reg=2 + * reg=3 + * + * Another additional format: %r is used to pass an additional format string + * and argument list recursively. Usage is typically: + * + * fn(otherstuff, fmt [, arg1, ... ] ) + * char *fmt; + * u_int arg1, ...; + * + * printf("prefix: %r, other stuff\n", fmt, &arg1); */ +#if defined(tahoe) +int consintr; +#endif + /*VARARGS1*/ printf(fmt, x1) char *fmt; unsigned x1; { +#if defined(tahoe) + register int savintr; - prf(fmt, &x1, 0); + savintr = consintr, consintr = 0; /* disable interrupts */ +#endif + prf(fmt, &x1, TOCONS | TOLOG, (struct tty *)0); + logwakeup(); +#if defined(tahoe) + consintr = savintr; /* reenable interrupts */ +#endif } /* - * Uprintf prints to the current user's terminal, - * guarantees not to sleep (so can be called by interrupt routines) - * and does no watermark checking - (so no verbose messages). + * Uprintf prints to the current user's terminal. + * It may block if the tty queue is overfull. + * No message is printed if the queue does not clear + * in a reasonable time. + * Should determine whether current terminal user is related + * to this process. */ /*VARARGS1*/ uprintf(fmt, x1) char *fmt; unsigned x1; { +#ifdef notdef + register struct proc *p; +#endif + register struct tty *tp; - prf(fmt, &x1, 2); + if ((tp = u.u_ttyp) == NULL) + return; +#ifdef notdef + if (tp->t_pgrp && (p = pfind(tp->t_pgrp))) + if (p->p_uid != u.u_uid) /* doesn't account for setuid */ + return; +#endif + if (ttycheckoutq(tp, 1)) + prf(fmt, &x1, TOTTY, tp); } -prf(fmt, adx, touser) +/* + * tprintf prints on the specified terminal (console if none) + * and logs the message. It is designed for error messages from + * single-open devices, and may be called from interrupt level + * (does not sleep). + */ +/*VARARGS2*/ +tprintf(tp, fmt, x1) + register struct tty *tp; + char *fmt; + unsigned x1; +{ + int flags = TOTTY | TOLOG; + + logpri(LOG_INFO); + if (tp == (struct tty *)NULL) { + tp = constty; + if (tp == (struct tty *)NULL) + tp = &cons; + } + if (ttycheckoutq(tp, 0) == 0) + flags = TOLOG; + prf(fmt, &x1, flags, tp); + logwakeup(); +} + +/* + * Log writes to the log buffer, + * and guarantees not to sleep (so can be called by interrupt routines). + * If there is no process reading the log yet, it writes to the console also. + */ +/*VARARGS2*/ +log(level, fmt, x1) + char *fmt; + unsigned x1; +{ + register s = splhigh(); + extern int log_open; + + logpri(level); + prf(fmt, &x1, TOLOG, (struct tty *)0); + splx(s); + if (!log_open) + prf(fmt, &x1, TOCONS, (struct tty *)0); + logwakeup(); +} + +logpri(level) + int level; +{ + + putchar('<', TOLOG, (struct tty *)0); + printn((u_long)level, 10, TOLOG, (struct tty *)0); + putchar('>', TOLOG, (struct tty *)0); +} + +/*VARARGS1*/ +addlog(fmt, x1) + char *fmt; + unsigned x1; +{ + register s = splhigh(); + + prf(fmt, &x1, TOLOG, (struct tty *)0); + splx(s); + if (!log_open) + prf(fmt, &x1, TOCONS, (struct tty *)0); + logwakeup(); +} + +prf(fmt, adx, flags, ttyp) register char *fmt; register u_int *adx; + struct tty *ttyp; { register int b, c, i; char *s; @@ -71,13 +204,13 @@ prf(fmt, adx, touser) loop: while ((c = *fmt++) != '%') { - if(c == '\0') + if (c == '\0') return; - putchar(c, touser); + putchar(c, flags, ttyp); } again: c = *fmt++; - /* THIS CODE IS VAX DEPENDENT IN HANDLING %l? AND %c */ + /* THIS CODE IS MACHINE DEPENDENT IN HANDLING %l? AND %c */ switch (c) { case 'l': @@ -86,51 +219,62 @@ again: b = 16; goto number; case 'd': case 'D': - case 'u': /* what a joke */ + b = -10; + goto number; + case 'u': b = 10; goto number; case 'o': case 'O': b = 8; number: - printn((u_long)*adx, b, touser); + printn((u_long)*adx, b, flags, ttyp); break; case 'c': b = *adx; +#if BYTE_ORDER == LITTLE_ENDIAN for (i = 24; i >= 0; i -= 8) if (c = (b >> i) & 0x7f) - putchar(c, touser); + putchar(c, flags, ttyp); +#endif +#if BYTE_ORDER == BIG_ENDIAN + if (c = (b & 0x7f)) + putchar(c, flags, ttyp); +#endif break; case 'b': b = *adx++; s = (char *)*adx; - printn((u_long)b, *s++, touser); + printn((u_long)b, *s++, flags, ttyp); any = 0; if (b) { - putchar('<', touser); while (i = *s++) { if (b & (1 << (i-1))) { - if (any) - putchar(',', touser); + putchar(any ? ',' : '<', flags, ttyp); any = 1; for (; (c = *s) > 32; s++) - putchar(c, touser); + putchar(c, flags, ttyp); } else for (; *s > 32; s++) ; } if (any) - putchar('>', touser); + putchar('>', flags, ttyp); } break; case 's': s = (char *)*adx; while (c = *s++) - putchar(c, touser); + putchar(c, flags, ttyp); + break; + + case 'r': + s = (char *)*adx++; + prf(s, (u_int *)*adx, flags, ttyp); break; case '%': - putchar('%', touser); + putchar('%', flags, ttyp); break; } adx++; @@ -141,15 +285,19 @@ number: * Printn prints a number n in base b. * We don't use recursion to avoid deep kernel stacks. */ -printn(n, b, touser) +printn(n, b, flags, ttyp) u_long n; + struct tty *ttyp; { char prbuf[11]; register char *cp; - if (b == 10 && (int)n < 0) { - putchar('-', touser); - n = (unsigned)(-(int)n); + if (b == -10) { + if ((int)n < 0) { + putchar('-', flags, ttyp); + n = (unsigned)(-(int)n); + } + b = -b; } cp = prbuf; do { @@ -157,7 +305,7 @@ printn(n, b, touser) n /= b; } while (n); do - putchar(*--cp, touser); + putchar(*--cp, flags, ttyp); while (cp > prbuf); } @@ -170,13 +318,23 @@ printn(n, b, touser) panic(s) char *s; { - int bootopt = RB_AUTOBOOT; + int bootopt = RB_AUTOBOOT | RB_DUMP; if (panicstr) bootopt |= RB_NOSYNC; - panicstr = s; + else { + panicstr = s; + } printf("panic: %s\n", s); - boot(RB_PANIC, bootopt); +#ifdef KADB + if (boothowto & RB_KDB) { + int x = splnet(); /* below kdb pri */ + + setsoftkdb(); + splx(x); + } +#endif + boot(bootopt); } /* @@ -186,20 +344,7 @@ tablefull(tab) char *tab; { - printf("%s: table is full\n", tab); -} - -/* - * Hard error is the preface to plaintive error messages - * about failing disk transfers. - */ -harderr(bp, cp) - struct buf *bp; - char *cp; -{ - - printf("%s%d%c: hard error sn%d ", cp, - dkunit(bp), 'a'+(minor(bp->b_dev)&07), bp->b_blkno); + log(LOG_ERR, "%s: table is full\n", tab); } /* @@ -208,33 +353,49 @@ harderr(bp, cp) * are saved in msgbuf for inspection later. */ /*ARGSUSED*/ -putchar(c, touser) +putchar(c, flags, tp) register int c; + struct tty *tp; { + extern int msgbufmapped; - if (touser) { - register struct tty *tp = u.u_ttyp; + if (panicstr) + constty = 0; + if ((flags & TOCONS) && tp == 0 && constty) { + tp = constty; + flags |= TOTTY; + } + if ((flags & TOCONS) && panicstr == 0 && tp == 0 && constty) { + tp = constty; + flags |= TOTTY; + } + if (flags & TOTTY) { + register s = spltty(); - if (tp && (tp->t_state&TS_CARR_ON)) { - register s = spl6(); + if (tp && (tp->t_state & (TS_CARR_ON | TS_ISOPEN)) == + (TS_CARR_ON | TS_ISOPEN)) { if (c == '\n') (void) ttyoutput('\r', tp); (void) ttyoutput(c, tp); ttstart(tp); - splx(s); - } - return; + flags &= ~TOCONS; + } else if ((flags & TOCONS) && tp == constty) + constty = 0; + splx(s); } - if (c != '\0' && c != '\r' && c != 0177 && mfpr(MAPEN)) { + if ((flags & TOLOG) && c != '\0' && c != '\r' && c != 0177 && + msgbufmapped) { if (msgbuf.msg_magic != MSG_MAGIC) { - msgbuf.msg_bufx = 0; + register int i; + msgbuf.msg_magic = MSG_MAGIC; + msgbuf.msg_bufx = msgbuf.msg_bufr = 0; + for (i=0; i < MSG_BSIZE; i++) + msgbuf.msg_bufc[i] = 0; } + msgbuf.msg_bufc[msgbuf.msg_bufx++] = c; if (msgbuf.msg_bufx < 0 || msgbuf.msg_bufx >= MSG_BSIZE) msgbuf.msg_bufx = 0; - msgbuf.msg_bufc[msgbuf.msg_bufx++] = c; } - if (c == 0) - return; - cnputc(c); + (*v_console)(c); }