lint; remove debug
[unix-history] / usr / src / sys / kern / subr_prf.c
CommitLineData
da7c5cc6
KM
1/*
2 * Copyright (c) 1982 Regents of the University of California.
3 * All rights reserved. The Berkeley software License Agreement
4 * specifies the terms and conditions for redistribution.
5 *
6f71a9f6 6 * @(#)subr_prf.c 6.10 (Berkeley) %G%
da7c5cc6 7 */
8cbb423c 8
94368568
JB
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 "dir.h"
18#include "user.h"
19#include "proc.h"
3358b36b 20#include "ioctl.h"
94368568 21#include "tty.h"
bd10af3f 22#include "syslog.h"
96d38f03 23
e3d5bfde
SL
24#ifdef vax
25#include "../vax/mtpr.h"
26#endif
27
34ef3482
RC
28#define TOCONS 0x1
29#define TOTTY 0x2
30#define TOLOG 0x4
31
8cbb423c
BJ
32/*
33 * In case console is off,
34 * panicstr contains argument to last
35 * call to panic.
36 */
8cbb423c
BJ
37char *panicstr;
38
39/*
40 * Scaled down version of C Library printf.
b725a0ca
BJ
41 * Used to print diagnostic information directly on console tty.
42 * Since it is not interrupt driven, all system activities are
43 * suspended. Printf should not be used for chit-chat.
44 *
45 * One additional format: %b is supported to decode error registers.
46 * Usage is:
47 * printf("reg=%b\n", regval, "<base><arg>*");
48 * Where <base> is the output base expressed as a control character,
49 * e.g. \10 gives octal; \20 gives hex. Each arg is a sequence of
50 * characters, the first of which gives the bit number to be inspected
51 * (origin 1), and the next characters (up to a control character, i.e.
52 * a character <= 32), give the name of the register. Thus
53 * printf("reg=%b\n", 3, "\10\2BITTWO\1BITONE\n");
54 * would produce output:
8d907ccf 55 * reg=3<BITTWO,BITONE>
8cbb423c
BJ
56 */
57/*VARARGS1*/
58printf(fmt, x1)
b725a0ca
BJ
59 char *fmt;
60 unsigned x1;
96d38f03
BJ
61{
62
34ef3482
RC
63 prf(fmt, &x1, TOCONS | TOLOG, (struct tty *)0);
64 logwakeup();
96d38f03
BJ
65}
66
843267b1 67/*
6f71a9f6
MK
68 * Uprintf prints to the current user's terminal.
69 * It may block if the tty queue is overfull.
70 * Should determine whether current terminal user is related
71 * to this process.
843267b1
BJ
72 */
73/*VARARGS1*/
74uprintf(fmt, x1)
b725a0ca 75 char *fmt;
843267b1 76 unsigned x1;
96d38f03 77{
6f71a9f6
MK
78 register struct proc *p;
79 register struct tty *tp;
96d38f03 80
6f71a9f6
MK
81 if ((tp = u.u_ttyp) == NULL)
82 return;
83#ifdef notdef
84 if (tp->t_pgrp && (p = pfind(tp->t_pgrp)))
85 if (p->p_uid != u.u_uid)
86 return;
87#endif
88 (void)ttycheckoutq(tp, 1);
89 prf(fmt, &x1, TOTTY, tp);
34ef3482
RC
90}
91
bd10af3f
MK
92/*
93 * tprintf prints on the specified terminal (console if none)
94 * and logs the message. It is designed for error messages from
6f71a9f6
MK
95 * single-open devices, and may be called from interrupt level
96 * (does not sleep).
bd10af3f 97 */
34ef3482 98/*VARARGS2*/
6f71a9f6
MK
99tprintf(tp, fmt, x1)
100 register struct tty *tp;
34ef3482
RC
101 char *fmt;
102 unsigned x1;
103{
6f71a9f6
MK
104 int flags = TOTTY | TOLOG;
105 extern struct tty cons;
34ef3482 106
6f71a9f6
MK
107 logpri(LOG_INFO);
108 if (tp == (struct tty *)NULL)
109 tp = &cons;
110 if (ttycheckoutq(tp, 0) == 0)
111 flags = TOLOG;
112 prf(fmt, &x1, flags, tp);
113 logwakeup();
34ef3482
RC
114}
115
116/*
117 * Log writes to the log buffer,
8d907ccf 118 * and guarantees not to sleep (so can be called by interrupt routines).
bd10af3f 119 * If there is no process reading the log yet, it writes to the console also.
34ef3482
RC
120 */
121/*VARARGS2*/
122log(level, fmt, x1)
123 char *fmt;
124 unsigned x1;
125{
126 register s = splhigh();
bd10af3f 127 extern int log_open;
34ef3482 128
6f71a9f6 129 logpri(level);
34ef3482
RC
130 prf(fmt, &x1, TOLOG, (struct tty *)0);
131 splx(s);
bd10af3f
MK
132 if (!log_open)
133 prf(fmt, &x1, TOCONS, (struct tty *)0);
34ef3482 134 logwakeup();
96d38f03
BJ
135}
136
6f71a9f6
MK
137logpri(level)
138 int level;
139{
140
141 putchar('<', TOLOG, (struct tty *)0);
142 printn(level, 10, TOLOG, (struct tty *)0);
143 putchar('>', TOLOG, (struct tty *)0);
144}
145
34ef3482 146prf(fmt, adx, flags, ttyp)
b725a0ca
BJ
147 register char *fmt;
148 register u_int *adx;
34ef3482 149 struct tty *ttyp;
8cbb423c 150{
d5726689 151 register int b, c, i;
8cbb423c 152 char *s;
3c79e4ff 153 int any;
8cbb423c 154
8cbb423c 155loop:
843267b1 156 while ((c = *fmt++) != '%') {
34ef3482 157 if (c == '\0')
8cbb423c 158 return;
34ef3482 159 putchar(c, flags, ttyp);
8cbb423c 160 }
843267b1 161again:
8cbb423c 162 c = *fmt++;
b725a0ca 163 /* THIS CODE IS VAX DEPENDENT IN HANDLING %l? AND %c */
843267b1
BJ
164 switch (c) {
165
166 case 'l':
167 goto again;
168 case 'x': case 'X':
169 b = 16;
170 goto number;
171 case 'd': case 'D':
172 case 'u': /* what a joke */
173 b = 10;
174 goto number;
175 case 'o': case 'O':
176 b = 8;
177number:
34ef3482 178 printn((u_long)*adx, b, flags, ttyp);
843267b1
BJ
179 break;
180 case 'c':
d5726689
BJ
181 b = *adx;
182 for (i = 24; i >= 0; i -= 8)
183 if (c = (b >> i) & 0x7f)
34ef3482 184 putchar(c, flags, ttyp);
843267b1 185 break;
3c79e4ff
BJ
186 case 'b':
187 b = *adx++;
188 s = (char *)*adx;
34ef3482 189 printn((u_long)b, *s++, flags, ttyp);
3c79e4ff
BJ
190 any = 0;
191 if (b) {
3c79e4ff
BJ
192 while (i = *s++) {
193 if (b & (1 << (i-1))) {
8d907ccf 194 putchar(any? ',' : '<', flags, ttyp);
3c79e4ff
BJ
195 any = 1;
196 for (; (c = *s) > 32; s++)
34ef3482 197 putchar(c, flags, ttyp);
3c79e4ff
BJ
198 } else
199 for (; *s > 32; s++)
200 ;
201 }
1ce587f2 202 if (any)
34ef3482 203 putchar('>', flags, ttyp);
3c79e4ff
BJ
204 }
205 break;
206
843267b1 207 case 's':
8cbb423c 208 s = (char *)*adx;
96d38f03 209 while (c = *s++)
34ef3482 210 putchar(c, flags, ttyp);
843267b1 211 break;
2bb8d359
BJ
212
213 case '%':
34ef3482 214 putchar('%', flags, ttyp);
2bb8d359 215 break;
8cbb423c
BJ
216 }
217 adx++;
218 goto loop;
219}
220
b725a0ca
BJ
221/*
222 * Printn prints a number n in base b.
223 * We don't use recursion to avoid deep kernel stacks.
224 */
34ef3482 225printn(n, b, flags, ttyp)
a0eab615 226 u_long n;
34ef3482 227 struct tty *ttyp;
8cbb423c 228{
d5726689 229 char prbuf[11];
843267b1 230 register char *cp;
8cbb423c 231
843267b1 232 if (b == 10 && (int)n < 0) {
34ef3482 233 putchar('-', flags, ttyp);
843267b1 234 n = (unsigned)(-(int)n);
8cbb423c 235 }
d5726689 236 cp = prbuf;
843267b1
BJ
237 do {
238 *cp++ = "0123456789abcdef"[n%b];
239 n /= b;
240 } while (n);
241 do
34ef3482 242 putchar(*--cp, flags, ttyp);
d5726689 243 while (cp > prbuf);
8cbb423c
BJ
244}
245
246/*
0dc06be8 247 * Panic is called on unresolvable fatal errors.
b725a0ca
BJ
248 * It prints "panic: mesg", and then reboots.
249 * If we are called twice, then we avoid trying to
250 * sync the disks as this often leads to recursive panics.
8cbb423c
BJ
251 */
252panic(s)
b725a0ca 253 char *s;
8cbb423c 254{
68503f9a 255 int bootopt = RB_AUTOBOOT;
843267b1 256
68503f9a
BJ
257 if (panicstr)
258 bootopt |= RB_NOSYNC;
cddce008 259 else {
961945a8 260 panicstr = s;
961945a8 261 }
a9c526c1 262 printf("panic: %s\n", s);
b725a0ca 263 boot(RB_PANIC, bootopt);
8cbb423c
BJ
264}
265
fdd11a14
BJ
266/*
267 * Warn that a system table is full.
268 */
269tablefull(tab)
270 char *tab;
271{
272
283ffc90 273 log(LOG_ERR, "%s: table is full\n", tab);
fdd11a14
BJ
274}
275
b725a0ca
BJ
276/*
277 * Hard error is the preface to plaintive error messages
fdd11a14 278 * about failing disk transfers.
b725a0ca 279 */
fdd11a14 280harderr(bp, cp)
3c79e4ff 281 struct buf *bp;
fdd11a14 282 char *cp;
8cbb423c
BJ
283{
284
fdd11a14 285 printf("%s%d%c: hard error sn%d ", cp,
c852160f 286 minor(bp->b_dev) >> 3, 'a'+(minor(bp->b_dev)&07), bp->b_blkno);
8cbb423c 287}
b725a0ca 288
96d38f03 289/*
843267b1 290 * Print a character on console or users terminal.
96d38f03
BJ
291 * If destination is console then the last MSGBUFS characters
292 * are saved in msgbuf for inspection later.
293 */
49c84d3f 294/*ARGSUSED*/
8d907ccf 295putchar(c, flags, tp)
843267b1 296 register int c;
8d907ccf 297 struct tty *tp;
96d38f03 298{
96d38f03 299
34ef3482 300 if (flags & TOTTY) {
6f71a9f6
MK
301 register s = spltty();
302
303 if (tp && (tp->t_state & (TS_CARR_ON | TS_ISOPEN)) ==
304 (TS_CARR_ON | TS_ISOPEN)) {
843267b1 305 if (c == '\n')
2752c877
BJ
306 (void) ttyoutput('\r', tp);
307 (void) ttyoutput(c, tp);
d11b28dc 308 ttstart(tp);
d11b28dc 309 }
6f71a9f6 310 splx(s);
d11b28dc 311 }
34ef3482 312 if ((flags & TOLOG) && c != '\0' && c != '\r' && c != 0177
b4e32d36 313#ifdef vax
cddce008
BJ
314 && mfpr(MAPEN)
315#endif
316 ) {
90f8d91f 317 if (msgbuf.msg_magic != MSG_MAGIC) {
76db4195
SL
318 register int i;
319
90f8d91f 320 msgbuf.msg_magic = MSG_MAGIC;
34ef3482 321 msgbuf.msg_bufx = msgbuf.msg_bufr = 0;
76db4195
SL
322 for (i=0; i < MSG_BSIZE; i++)
323 msgbuf.msg_bufc[i] = 0;
90f8d91f
BJ
324 }
325 if (msgbuf.msg_bufx < 0 || msgbuf.msg_bufx >= MSG_BSIZE)
326 msgbuf.msg_bufx = 0;
327 msgbuf.msg_bufc[msgbuf.msg_bufx++] = c;
96d38f03 328 }
34ef3482
RC
329 if ((flags & TOCONS) && c != '\0')
330 cnputc(c);
96d38f03 331}