subr_prf.c revision 1.42 1 /* $NetBSD: subr_prf.c,v 1.42 1997/06/26 00:43:10 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 case '.':
445 padc = '0';
446 goto reswitch;
447 case '1': case '2': case '3': case '4':
448 case '5': case '6': case '7': case '8': case '9':
449 for (width = 0;; ++fmt) {
450 width = width * 10 + ch - '0';
451 ch = *fmt;
452 if (ch < '0' || ch > '9')
453 break;
454 }
455 goto reswitch;
456 case 'l':
457 flags |= LONGINT;
458 goto reswitch;
459 case 'q':
460 flags |= QUADINT;
461 goto reswitch;
462 case 'b':
463 ul = va_arg(ap, int);
464 p = va_arg(ap, char *);
465 for (q = ksnprintn(ul, *p++, NULL, snbuf,
466 sizeof(snbuf)); (ch = *q--) != 0;)
467 putchar(ch, oflags, tp);
468
469 if (!ul)
470 break;
471
472 for (tmp = 0; (n = *p++) != 0;) {
473 if (ul & (1 << (n - 1))) {
474 putchar(tmp ? ',' : '<', oflags, tp);
475 for (; (n = *p) > ' '; ++p)
476 putchar(n, oflags, tp);
477 tmp = 1;
478 } else
479 for (; *p > ' '; ++p)
480 continue;
481 }
482 if (tmp)
483 putchar('>', oflags, tp);
484 break;
485 case 'c':
486 putchar(va_arg(ap, int), oflags, tp);
487 break;
488 #ifndef __powerpc__ /* XXX XXX XXX */
489 case ':':
490 p = va_arg(ap, char *);
491 kprintf(p, oflags, tp, va_arg(ap, va_list));
492 break;
493 #endif /* __powerpc__ */ /* XXX XXX XXX */
494 case 's':
495 if ((p = va_arg(ap, char *)) == NULL)
496 p = "(null)";
497 while ((ch = *p++) != 0)
498 putchar(ch, oflags, tp);
499 break;
500 case 'd':
501 ul = SARG();
502 if ((quad_t)ul < 0) {
503 putchar('-', oflags, tp);
504 ul = -ul;
505 }
506 base = 10;
507 goto number;
508 case 'o':
509 ul = UARG();
510 base = 8;
511 goto number;
512 case 'u':
513 ul = UARG();
514 base = 10;
515 goto number;
516 case 'p':
517 putchar('0', oflags, tp);
518 putchar('x', oflags, tp);
519 ul = (u_long)va_arg(ap, void *);
520 base = 16;
521 goto number;
522 case 'x':
523 ul = UARG();
524 base = 16;
525 number: p = ksnprintn(ul, base, &tmp, snbuf, sizeof(snbuf));
526 if (width && (width -= tmp) > 0)
527 while (width--)
528 putchar(padc, oflags, tp);
529 while ((ch = *p--) != 0)
530 putchar(ch, oflags, tp);
531 break;
532 default:
533 putchar('%', oflags, tp);
534 /* flags??? */
535 /* FALLTHROUGH */
536 case '%':
537 putchar(ch, oflags, tp);
538 }
539 }
540 }
541
542 /*
543 * Print a character on console or users terminal. If destination is
544 * the console then the last MSGBUFS characters are saved in msgbuf for
545 * inspection later.
546 */
547 static void
548 putchar(c, flags, tp)
549 register int c;
550 int flags;
551 struct tty *tp;
552 {
553 extern int msgbufmapped;
554 register struct msgbuf *mbp;
555
556 if (panicstr)
557 constty = NULL;
558 if ((flags & TOCONS) && tp == NULL && constty) {
559 tp = constty;
560 flags |= TOTTY;
561 }
562 if ((flags & TOTTY) && tp && tputchar(c, tp) < 0 &&
563 (flags & TOCONS) && tp == constty)
564 constty = NULL;
565 if ((flags & TOLOG) &&
566 c != '\0' && c != '\r' && c != 0177 && msgbufmapped) {
567 mbp = msgbufp;
568 if (mbp->msg_magic != MSG_MAGIC) {
569 bzero((caddr_t)mbp, sizeof(*mbp));
570 mbp->msg_magic = MSG_MAGIC;
571 }
572 mbp->msg_bufc[mbp->msg_bufx++] = c;
573 if (mbp->msg_bufx < 0 || mbp->msg_bufx >= MSG_BSIZE)
574 mbp->msg_bufx = 0;
575 }
576 if ((flags & TOCONS) && constty == NULL && c != '\0')
577 (*v_putc)(c);
578 }
579
580 /*
581 * Scaled down version of sprintf(3).
582 */
583 int
584 #ifdef __STDC__
585 sprintf(char *buf, const char *cfmt, ...)
586 #else
587 sprintf(buf, cfmt, va_alist)
588 char *buf;
589 const char *cfmt;
590 va_dcl
591 #endif
592 {
593 register const char *fmt = cfmt;
594 register char *p, *bp;
595 register int ch, base;
596 u_quad_t ul;
597 int flags, tmp, width;
598 va_list ap;
599 char padc, snbuf[KSNPRINTN_BUFSIZE];
600
601 va_start(ap, cfmt);
602 for (bp = buf; ; ) {
603 padc = ' ';
604 width = 0;
605 while ((ch = *(const u_char *)fmt++) != '%')
606 if ((*bp++ = ch) == '\0')
607 return ((bp - buf) - 1);
608
609 flags = 0;
610 reswitch: switch (ch = *(const u_char *)fmt++) {
611 case '0':
612 padc = '0';
613 goto reswitch;
614 case '1': case '2': case '3': case '4':
615 case '5': case '6': case '7': case '8': case '9':
616 for (width = 0;; ++fmt) {
617 width = width * 10 + ch - '0';
618 ch = *fmt;
619 if (ch < '0' || ch > '9')
620 break;
621 }
622 goto reswitch;
623 case 'l':
624 flags |= LONGINT;
625 goto reswitch;
626 case 'q':
627 flags |= QUADINT;
628 goto reswitch;
629 /* case 'b': ... break; XXX */
630 case 'c':
631 *bp++ = va_arg(ap, int);
632 break;
633 /* case 'r': ... break; XXX */
634 case 's':
635 p = va_arg(ap, char *);
636 while ((*bp++ = *p++) != 0)
637 continue;
638 --bp;
639 break;
640 case 'd':
641 ul = SARG();
642 if ((quad_t)ul < 0) {
643 *bp++ = '-';
644 ul = -ul;
645 }
646 base = 10;
647 goto number;
648 case 'o':
649 ul = UARG();
650 base = 8;
651 goto number;
652 case 'u':
653 ul = UARG();
654 base = 10;
655 goto number;
656 case 'p':
657 *bp++ = '0';
658 *bp++ = 'x';
659 ul = (u_long)va_arg(ap, void *);
660 base = 16;
661 goto number;
662 case 'x':
663 ul = UARG();
664 base = 16;
665 number: p = ksnprintn(ul, base, &tmp, snbuf, sizeof(snbuf));
666 if (width && (width -= tmp) > 0)
667 while (width--)
668 *bp++ = padc;
669 while ((ch = *p--) != 0)
670 *bp++ = ch;
671 break;
672 default:
673 *bp++ = '%';
674 /* flags??? */
675 /* FALLTHROUGH */
676 case '%':
677 *bp++ = ch;
678 }
679 }
680 va_end(ap);
681 }
682
683 /*
684 * Put a number (base <= 16) in a buffer in reverse order; return an
685 * optional length and a pointer to the NULL terminated (preceded?)
686 * buffer.
687 */
688 static char *
689 ksnprintn(ul, base, lenp, buf, buflen)
690 register u_quad_t ul;
691 register int base, *lenp;
692 char *buf;
693 size_t buflen;
694 {
695 register char *p;
696
697 p = buf;
698 *p = '\0'; /* ensure NULL `termination' */
699
700 /*
701 * Don't even bother of the buffer's not big enough. No
702 * value at all is better than a wrong value, and we
703 * have a lot of control over the buffer that's passed
704 * to this function, since it's not exported.
705 */
706 if (buflen < KSNPRINTN_BUFSIZE)
707 return (p);
708
709 do {
710 *++p = "0123456789abcdef"[ul % base];
711 } while (ul /= base);
712 if (lenp)
713 *lenp = p - buf;
714 return (p);
715 }
716
717 /*
718 * Print a bitmask into the provided buffer, and return a pointer
719 * to that buffer.
720 */
721 char *
722 bitmask_snprintf(ul, p, buf, buflen)
723 u_long ul;
724 const char *p;
725 char *buf;
726 size_t buflen;
727 {
728 char *bp, *q;
729 size_t left;
730 register int n;
731 int ch, tmp;
732 char snbuf[KSNPRINTN_BUFSIZE];
733
734 bp = buf;
735 bzero(buf, buflen);
736
737 /*
738 * Always leave room for the trailing NULL.
739 */
740 left = buflen - 1;
741
742 /*
743 * Print the value into the buffer. Abort if there's not
744 * enough room.
745 */
746 if (buflen < KSNPRINTN_BUFSIZE)
747 return (buf);
748
749 for (q = ksnprintn(ul, *p++, NULL, snbuf, sizeof(snbuf));
750 (ch = *q--) != 0;) {
751 *bp++ = ch;
752 left--;
753 }
754
755 /*
756 * If the value we printed was 0, or if we don't have room for
757 * "<x>", we're done.
758 */
759 if (ul == 0 || left < 3)
760 return (buf);
761
762 #define PUTBYTE(b, c, l) \
763 *(b)++ = (c); \
764 if (--(l) == 0) \
765 goto out;
766
767 for (tmp = 0; (n = *p++) != 0;) {
768 if (ul & (1 << (n - 1))) {
769 PUTBYTE(bp, tmp ? ',' : '<', left);
770 for (; (n = *p) > ' '; ++p) {
771 PUTBYTE(bp, n, left);
772 }
773 tmp = 1;
774 } else
775 for (; *p > ' '; ++p)
776 continue;
777 }
778 if (tmp)
779 *bp = '>';
780
781 #undef PUTBYTE
782
783 out:
784 return (buf);
785 }
786