subr_prf.c revision 1.43.4.1 1 /* $NetBSD: subr_prf.c,v 1.43.4.1 1997/09/22 06:33:49 thorpej Exp $ */
2
3 /*-
4 * Copyright (c) 1986, 1988, 1991, 1993
5 * The Regents of the University of California. All rights reserved.
6 * (c) UNIX System Laboratories, Inc.
7 * All or some portions of this file are derived from material licensed
8 * to the University of California by American Telephone and Telegraph
9 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
10 * the permission of UNIX System Laboratories, Inc.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution.
20 * 3. All advertising materials mentioning features or use of this software
21 * must display the following acknowledgement:
22 * This product includes software developed by the University of
23 * California, Berkeley and its contributors.
24 * 4. Neither the name of the University nor the names of its contributors
25 * may be used to endorse or promote products derived from this software
26 * without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
29 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
32 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
36 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
37 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38 * SUCH DAMAGE.
39 *
40 * @(#)subr_prf.c 8.3 (Berkeley) 1/21/94
41 */
42
43 #include <sys/param.h>
44 #include <sys/systm.h>
45 #include <sys/buf.h>
46 #include <sys/conf.h>
47 #include <sys/reboot.h>
48 #include <sys/msgbuf.h>
49 #include <sys/proc.h>
50 #include <sys/ioctl.h>
51 #include <sys/vnode.h>
52 #include <sys/file.h>
53 #include <sys/tty.h>
54 #include <sys/tprintf.h>
55 #include <sys/syslog.h>
56 #include <sys/malloc.h>
57
58 #include <dev/cons.h>
59
60 /*
61 * Note that stdarg.h and the ANSI style va_start macro is used for both
62 * ANSI and traditional C compilers.
63 * XXX: This requires that stdarg.h defines: va_alist, va_dcl
64 */
65 #include <machine/stdarg.h>
66
67 #include "ipkdb.h"
68
69 #ifdef KADB
70 #include <machine/kdbparam.h>
71 #endif
72 #ifdef KGDB
73 #include <sys/kgdb.h>
74 #include <machine/cpu.h>
75 #endif
76
77 #define TOCONS 0x01
78 #define TOTTY 0x02
79 #define TOLOG 0x04
80
81 /*
82 * This is the size of the buffer that should be passed to ksnprintn().
83 * It's the length of a long in base 8, plus NULL.
84 */
85 #define KSNPRINTN_BUFSIZE (sizeof(quad_t) * NBBY / 3 + 2)
86
87 struct tty *constty; /* pointer to console "window" tty */
88
89 void (*v_putc) __P((int)) = cnputc; /* routine to putc on virtual console */
90
91 static void putchar __P((int, int, struct tty *));
92 static char *ksnprintn __P((u_quad_t, int, int *, char *, size_t));
93 void kprintf __P((const char *, int, struct tty *, va_list));
94
95 int consintr = 1; /* Ok to handle console interrupts? */
96
97 /*
98 * Variable panicstr contains argument to first call to panic; used as flag
99 * to indicate that the kernel has already called panic.
100 */
101 const char *panicstr;
102
103 /*
104 * Panic is called on unresolvable fatal errors. It prints "panic: mesg",
105 * and then reboots. If we are called twice, then we avoid trying to sync
106 * the disks as this often leads to recursive panics.
107 */
108 void
109 #ifdef __STDC__
110 panic(const char *fmt, ...)
111 #else
112 panic(fmt, va_alist)
113 char *fmt;
114 va_dcl
115 #endif
116 {
117 int bootopt;
118 va_list ap;
119
120 bootopt = RB_AUTOBOOT | RB_DUMP;
121 if (panicstr)
122 bootopt |= RB_NOSYNC;
123 else
124 panicstr = fmt;
125
126 va_start(ap, fmt);
127 #ifdef __powerpc__ /* XXX */
128 printf("panic: "); /* XXX */
129 vprintf(fmt, ap); /* XXX */
130 printf("\n"); /* XXX */
131 #else /* XXX */
132 printf("panic: %:\n", fmt, ap); /* XXX */
133 #endif /* XXX */
134 va_end(ap);
135
136 #if NIPKDB > 0
137 ipkdb_panic();
138 #endif
139 #ifdef KGDB
140 kgdb_panic();
141 #endif
142 #ifdef KADB
143 if (boothowto & RB_KDB)
144 kdbpanic();
145 #endif
146 #ifdef DDB
147 if (db_onpanic)
148 Debugger();
149 #endif
150 cpu_reboot(bootopt, NULL);
151 }
152
153 /*
154 * Warn that a system table is full.
155 */
156 void
157 tablefull(tab)
158 const char *tab;
159 {
160
161 log(LOG_ERR, "%s: table is full\n", tab);
162 }
163
164 /*
165 * Uprintf prints to the controlling terminal for the current process.
166 * It may block if the tty queue is overfull. No message is printed if
167 * the queue does not clear in a reasonable time.
168 */
169 void
170 #ifdef __STDC__
171 uprintf(const char *fmt, ...)
172 #else
173 uprintf(fmt, va_alist)
174 char *fmt;
175 va_dcl
176 #endif
177 {
178 register struct proc *p = curproc;
179 va_list ap;
180
181 if (p->p_flag & P_CONTROLT && p->p_session->s_ttyvp) {
182 va_start(ap, fmt);
183 kprintf(fmt, TOTTY, p->p_session->s_ttyp, ap);
184 va_end(ap);
185 }
186 }
187
188 tpr_t
189 tprintf_open(p)
190 register struct proc *p;
191 {
192
193 if (p->p_flag & P_CONTROLT && p->p_session->s_ttyvp) {
194 SESSHOLD(p->p_session);
195 return ((tpr_t) p->p_session);
196 }
197 return ((tpr_t) NULL);
198 }
199
200 void
201 tprintf_close(sess)
202 tpr_t sess;
203 {
204
205 if (sess)
206 SESSRELE((struct session *) sess);
207 }
208
209 /*
210 * tprintf prints on the controlling terminal associated
211 * with the given session.
212 */
213 void
214 #ifdef __STDC__
215 tprintf(tpr_t tpr, const char *fmt, ...)
216 #else
217 tprintf(tpr, fmt, va_alist)
218 tpr_t tpr;
219 char *fmt;
220 va_dcl
221 #endif
222 {
223 register struct session *sess = (struct session *)tpr;
224 struct tty *tp = NULL;
225 int flags = TOLOG;
226 va_list ap;
227
228 logpri(LOG_INFO);
229 if (sess && sess->s_ttyvp && ttycheckoutq(sess->s_ttyp, 0)) {
230 flags |= TOTTY;
231 tp = sess->s_ttyp;
232 }
233 va_start(ap, fmt);
234 kprintf(fmt, flags, tp, ap);
235 va_end(ap);
236 logwakeup();
237 }
238
239 /*
240 * Ttyprintf displays a message on a tty; it should be used only by
241 * the tty driver, or anything that knows the underlying tty will not
242 * be revoke(2)'d away. Other callers should use tprintf.
243 */
244 void
245 #ifdef __STDC__
246 ttyprintf(struct tty *tp, const char *fmt, ...)
247 #else
248 ttyprintf(tp, fmt, va_alist)
249 struct tty *tp;
250 char *fmt;
251 va_dcl
252 #endif
253 {
254 va_list ap;
255
256 va_start(ap, fmt);
257 kprintf(fmt, TOTTY, tp, ap);
258 va_end(ap);
259 }
260
261 extern int log_open;
262
263 /*
264 * Log writes to the log buffer, and guarantees not to sleep (so can be
265 * called by interrupt routines). If there is no process reading the
266 * log yet, it writes to the console also.
267 */
268 void
269 #ifdef __STDC__
270 log(int level, const char *fmt, ...)
271 #else
272 log(level, fmt, va_alist)
273 int level;
274 char *fmt;
275 va_dcl
276 #endif
277 {
278 register int s;
279 va_list ap;
280
281 s = splhigh();
282 logpri(level);
283 va_start(ap, fmt);
284 kprintf(fmt, TOLOG, NULL, ap);
285 splx(s);
286 va_end(ap);
287 if (!log_open) {
288 va_start(ap, fmt);
289 kprintf(fmt, TOCONS, NULL, ap);
290 va_end(ap);
291 }
292 logwakeup();
293 }
294
295 void
296 logpri(level)
297 int level;
298 {
299 register int ch;
300 register char *p;
301 char snbuf[KSNPRINTN_BUFSIZE];
302
303 putchar('<', TOLOG, NULL);
304 for (p = ksnprintn((u_long)level, 10, NULL, snbuf, sizeof(snbuf));
305 (ch = *p--) != 0;)
306 putchar(ch, TOLOG, NULL);
307 putchar('>', TOLOG, NULL);
308 }
309
310 void
311 #ifdef __STDC__
312 addlog(const char *fmt, ...)
313 #else
314 addlog(fmt, va_alist)
315 char *fmt;
316 va_dcl
317 #endif
318 {
319 register int s;
320 va_list ap;
321
322 s = splhigh();
323 va_start(ap, fmt);
324 kprintf(fmt, TOLOG, NULL, ap);
325 splx(s);
326 va_end(ap);
327 if (!log_open) {
328 va_start(ap, fmt);
329 kprintf(fmt, TOCONS, NULL, ap);
330 va_end(ap);
331 }
332 logwakeup();
333 }
334
335 void
336 #ifdef __STDC__
337 printf(const char *fmt, ...)
338 #else
339 printf(fmt, va_alist)
340 char *fmt;
341 va_dcl
342 #endif
343 {
344 va_list ap;
345 register int savintr;
346
347 savintr = consintr; /* disable interrupts */
348 consintr = 0;
349 va_start(ap, fmt);
350 kprintf(fmt, TOCONS | TOLOG, NULL, ap);
351 va_end(ap);
352 if (!panicstr)
353 logwakeup();
354 consintr = savintr; /* reenable interrupts */
355 }
356
357 #ifdef __powerpc__ /* XXX XXX XXX */
358 void
359 vprintf(fmt, ap)
360 const char *fmt;
361 va_list ap;
362 {
363 register int savintr;
364
365 savintr = consintr; /* disable interrupts */
366 consintr = 0;
367 kprintf(fmt, TOCONS | TOLOG, NULL, ap);
368 if (!panicstr)
369 logwakeup();
370 consintr = savintr; /* reenable interrupts */
371 }
372 #endif /* __powerpc__ */ /* XXX XXX XXX */
373
374 /*
375 * Scaled down version of printf(3).
376 *
377 * Two additional formats:
378 *
379 * The format %b is supported to decode error registers.
380 * Its usage is:
381 *
382 * printf("reg=%b\n", regval, "<base><arg>*");
383 *
384 * where <base> is the output base expressed as a control character, e.g.
385 * \10 gives octal; \20 gives hex. Each arg is a sequence of characters,
386 * the first of which gives the bit number to be inspected (origin 1), and
387 * the next characters (up to a control character, i.e. a character <= 32),
388 * give the name of the register. Thus:
389 *
390 * kprintf("reg=%b\n", 3, "\10\2BITTWO\1BITONE\n");
391 *
392 * would produce output:
393 *
394 * reg=3<BITTWO,BITONE>
395 *
396 * The format %: passes an additional format string and argument list
397 * recursively. Its usage is:
398 *
399 * fn(char *fmt, ...)
400 * {
401 * va_list ap;
402 * va_start(ap, fmt);
403 * printf("prefix: %: suffix\n", fmt, ap);
404 * va_end(ap);
405 * }
406 *
407 * Space or zero padding and a field width are supported for the numeric
408 * formats only.
409 */
410 #define LONGINT 0x010 /* long integer */
411 #define QUADINT 0x020 /* quad integer */
412 #define SARG() \
413 (flags&QUADINT ? va_arg(ap, quad_t) : \
414 flags&LONGINT ? va_arg(ap, long) : \
415 (long)va_arg(ap, int))
416 #define UARG() \
417 (flags&QUADINT ? va_arg(ap, u_quad_t) : \
418 flags&LONGINT ? va_arg(ap, u_long) : \
419 (u_long)va_arg(ap, u_int))
420 void
421 kprintf(fmt, oflags, tp, ap)
422 register const char *fmt;
423 int oflags;
424 struct tty *tp;
425 va_list ap;
426 {
427 register char *p, *q;
428 register int ch, n;
429 u_quad_t ul;
430 int base, flags, tmp, width;
431 char padc, snbuf[KSNPRINTN_BUFSIZE];
432
433 for (;;) {
434 padc = ' ';
435 width = 0;
436 while ((ch = *(const u_char *)fmt++) != '%') {
437 if (ch == '\0')
438 return;
439 putchar(ch, oflags, tp);
440 }
441 flags = 0;
442 reswitch: switch (ch = *(const u_char *)fmt++) {
443 case '\0':
444 /* XXX Print the last format character? */
445 return;
446 case '0':
447 case '.':
448 padc = '0';
449 goto reswitch;
450 case '1': case '2': case '3': case '4':
451 case '5': case '6': case '7': case '8': case '9':
452 for (width = 0;; ++fmt) {
453 width = width * 10 + ch - '0';
454 ch = *fmt;
455 if (ch < '0' || ch > '9')
456 break;
457 }
458 goto reswitch;
459 case 'l':
460 flags |= LONGINT;
461 goto reswitch;
462 case 'q':
463 flags |= QUADINT;
464 goto reswitch;
465 case 'b':
466 ul = va_arg(ap, int);
467 p = va_arg(ap, char *);
468 for (q = ksnprintn(ul, *p++, NULL, snbuf,
469 sizeof(snbuf)); (ch = *q--) != 0;)
470 putchar(ch, oflags, tp);
471
472 if (!ul)
473 break;
474
475 for (tmp = 0; (n = *p++) != 0;) {
476 if (ul & (1 << (n - 1))) {
477 putchar(tmp ? ',' : '<', oflags, tp);
478 for (; (n = *p) > ' '; ++p)
479 putchar(n, oflags, tp);
480 tmp = 1;
481 } else
482 for (; *p > ' '; ++p)
483 continue;
484 }
485 if (tmp)
486 putchar('>', oflags, tp);
487 break;
488 case 'c':
489 putchar(va_arg(ap, int), oflags, tp);
490 break;
491 #ifndef __powerpc__ /* XXX XXX XXX */
492 case ':':
493 p = va_arg(ap, char *);
494 kprintf(p, oflags, tp, va_arg(ap, va_list));
495 break;
496 #endif /* __powerpc__ */ /* XXX XXX XXX */
497 case 's':
498 if ((p = va_arg(ap, char *)) == NULL)
499 p = "(null)";
500 while ((ch = *p++) != 0)
501 putchar(ch, oflags, tp);
502 break;
503 case 'd':
504 ul = SARG();
505 if ((quad_t)ul < 0) {
506 putchar('-', oflags, tp);
507 ul = -ul;
508 }
509 base = 10;
510 goto number;
511 case 'o':
512 ul = UARG();
513 base = 8;
514 goto number;
515 case 'u':
516 ul = UARG();
517 base = 10;
518 goto number;
519 case 'p':
520 putchar('0', oflags, tp);
521 putchar('x', oflags, tp);
522 ul = (u_long)va_arg(ap, void *);
523 base = 16;
524 goto number;
525 case 'x':
526 ul = UARG();
527 base = 16;
528 number: p = ksnprintn(ul, base, &tmp, snbuf, sizeof(snbuf));
529 if (width && (width -= tmp) > 0)
530 while (width--)
531 putchar(padc, oflags, tp);
532 while ((ch = *p--) != 0)
533 putchar(ch, oflags, tp);
534 break;
535 default:
536 putchar('%', oflags, tp);
537 /* flags??? */
538 /* FALLTHROUGH */
539 case '%':
540 putchar(ch, oflags, tp);
541 }
542 }
543 }
544
545 /*
546 * Print a character on console or users terminal. If destination is
547 * the console then the last MSGBUFS characters are saved in msgbuf for
548 * inspection later.
549 */
550 static void
551 putchar(c, flags, tp)
552 register int c;
553 int flags;
554 struct tty *tp;
555 {
556 register struct kern_msgbuf *mbp;
557
558 if (panicstr)
559 constty = NULL;
560 if ((flags & TOCONS) && tp == NULL && constty) {
561 tp = constty;
562 flags |= TOTTY;
563 }
564 if ((flags & TOTTY) && tp && tputchar(c, tp) < 0 &&
565 (flags & TOCONS) && tp == constty)
566 constty = NULL;
567 if ((flags & TOLOG) &&
568 c != '\0' && c != '\r' && c != 0177 && msgbufenabled) {
569 mbp = msgbufp;
570 if (mbp->msg_magic != MSG_MAGIC) {
571 /*
572 * Arguably should panic or somehow notify the
573 * user... but how? Panic may be too drastic,
574 * and would obliterate the message being kicked
575 * out (maybe a panic itself), and printf
576 * would invoke us recursively. Silently punt
577 * for now. If syslog is running, it should
578 * notice.
579 */
580 msgbufenabled = 0;
581 } else {
582 mbp->msg_bufc[mbp->msg_bufx++] = c;
583 if (mbp->msg_bufx < 0 || mbp->msg_bufx >= mbp->msg_bufs)
584 mbp->msg_bufx = 0;
585 }
586 }
587 if ((flags & TOCONS) && constty == NULL && c != '\0')
588 (*v_putc)(c);
589 }
590
591 /*
592 * Scaled down version of sprintf(3).
593 */
594 int
595 #ifdef __STDC__
596 sprintf(char *buf, const char *cfmt, ...)
597 #else
598 sprintf(buf, cfmt, va_alist)
599 char *buf;
600 const char *cfmt;
601 va_dcl
602 #endif
603 {
604 register const char *fmt = cfmt;
605 register char *p, *bp;
606 register int ch, base;
607 u_quad_t ul;
608 int flags, tmp, width;
609 va_list ap;
610 char padc, snbuf[KSNPRINTN_BUFSIZE];
611
612 va_start(ap, cfmt);
613 for (bp = buf; ; ) {
614 padc = ' ';
615 width = 0;
616 while ((ch = *(const u_char *)fmt++) != '%')
617 if ((*bp++ = ch) == '\0')
618 return ((bp - buf) - 1);
619
620 flags = 0;
621 reswitch: switch (ch = *(const u_char *)fmt++) {
622 case '\0':
623 /* XXX Store the last format character? */
624 *bp++ = '\0';
625 return ((bp - buf) - 1);
626 case '0':
627 padc = '0';
628 goto reswitch;
629 case '1': case '2': case '3': case '4':
630 case '5': case '6': case '7': case '8': case '9':
631 for (width = 0;; ++fmt) {
632 width = width * 10 + ch - '0';
633 ch = *fmt;
634 if (ch < '0' || ch > '9')
635 break;
636 }
637 goto reswitch;
638 case 'l':
639 flags |= LONGINT;
640 goto reswitch;
641 case 'q':
642 flags |= QUADINT;
643 goto reswitch;
644 /* case 'b': ... break; XXX */
645 case 'c':
646 *bp++ = va_arg(ap, int);
647 break;
648 /* case 'r': ... break; XXX */
649 case 's':
650 p = va_arg(ap, char *);
651 while ((*bp++ = *p++) != 0)
652 continue;
653 --bp;
654 break;
655 case 'd':
656 ul = SARG();
657 if ((quad_t)ul < 0) {
658 *bp++ = '-';
659 ul = -ul;
660 }
661 base = 10;
662 goto number;
663 case 'o':
664 ul = UARG();
665 base = 8;
666 goto number;
667 case 'u':
668 ul = UARG();
669 base = 10;
670 goto number;
671 case 'p':
672 *bp++ = '0';
673 *bp++ = 'x';
674 ul = (u_long)va_arg(ap, void *);
675 base = 16;
676 goto number;
677 case 'x':
678 ul = UARG();
679 base = 16;
680 number: p = ksnprintn(ul, base, &tmp, snbuf, sizeof(snbuf));
681 if (width && (width -= tmp) > 0)
682 while (width--)
683 *bp++ = padc;
684 while ((ch = *p--) != 0)
685 *bp++ = ch;
686 break;
687 default:
688 *bp++ = '%';
689 /* flags??? */
690 /* FALLTHROUGH */
691 case '%':
692 *bp++ = ch;
693 }
694 }
695 va_end(ap);
696 }
697
698 /*
699 * Put a number (base <= 16) in a buffer in reverse order; return an
700 * optional length and a pointer to the NULL terminated (preceded?)
701 * buffer.
702 */
703 static char *
704 ksnprintn(ul, base, lenp, buf, buflen)
705 register u_quad_t ul;
706 register int base, *lenp;
707 char *buf;
708 size_t buflen;
709 {
710 register char *p;
711
712 p = buf;
713 *p = '\0'; /* ensure NULL `termination' */
714
715 /*
716 * Don't even bother of the buffer's not big enough. No
717 * value at all is better than a wrong value, and we
718 * have a lot of control over the buffer that's passed
719 * to this function, since it's not exported.
720 */
721 if (buflen < KSNPRINTN_BUFSIZE)
722 return (p);
723
724 do {
725 *++p = "0123456789abcdef"[ul % base];
726 } while (ul /= base);
727 if (lenp)
728 *lenp = p - buf;
729 return (p);
730 }
731
732 /*
733 * Print a bitmask into the provided buffer, and return a pointer
734 * to that buffer.
735 */
736 char *
737 bitmask_snprintf(ul, p, buf, buflen)
738 u_long ul;
739 const char *p;
740 char *buf;
741 size_t buflen;
742 {
743 char *bp, *q;
744 size_t left;
745 register int n;
746 int ch, tmp;
747 char snbuf[KSNPRINTN_BUFSIZE];
748
749 bp = buf;
750 bzero(buf, buflen);
751
752 /*
753 * Always leave room for the trailing NULL.
754 */
755 left = buflen - 1;
756
757 /*
758 * Print the value into the buffer. Abort if there's not
759 * enough room.
760 */
761 if (buflen < KSNPRINTN_BUFSIZE)
762 return (buf);
763
764 for (q = ksnprintn(ul, *p++, NULL, snbuf, sizeof(snbuf));
765 (ch = *q--) != 0;) {
766 *bp++ = ch;
767 left--;
768 }
769
770 /*
771 * If the value we printed was 0, or if we don't have room for
772 * "<x>", we're done.
773 */
774 if (ul == 0 || left < 3)
775 return (buf);
776
777 #define PUTBYTE(b, c, l) \
778 *(b)++ = (c); \
779 if (--(l) == 0) \
780 goto out;
781
782 for (tmp = 0; (n = *p++) != 0;) {
783 if (ul & (1 << (n - 1))) {
784 PUTBYTE(bp, tmp ? ',' : '<', left);
785 for (; (n = *p) > ' '; ++p) {
786 PUTBYTE(bp, n, left);
787 }
788 tmp = 1;
789 } else
790 for (; *p > ' '; ++p)
791 continue;
792 }
793 if (tmp)
794 *bp = '>';
795
796 #undef PUTBYTE
797
798 out:
799 return (buf);
800 }
801