subr_prf.c revision 1.67 1 /* $NetBSD: subr_prf.c,v 1.67 2000/03/22 20:58:30 ws 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.4 (Berkeley) 5/4/95
41 */
42
43 #include "opt_ddb.h"
44 #include "opt_ipkdb.h"
45 #include "opt_multiprocessor.h"
46
47 #include <sys/param.h>
48 #include <sys/systm.h>
49 #include <sys/buf.h>
50 #include <sys/conf.h>
51 #include <sys/reboot.h>
52 #include <sys/msgbuf.h>
53 #include <sys/proc.h>
54 #include <sys/ioctl.h>
55 #include <sys/vnode.h>
56 #include <sys/file.h>
57 #include <sys/tty.h>
58 #include <sys/tprintf.h>
59 #include <sys/syslog.h>
60 #include <sys/malloc.h>
61 #include <sys/lock.h>
62
63 #include <dev/cons.h>
64
65 #ifdef DDB
66 #include <ddb/ddbvar.h>
67 #endif
68
69 #ifdef IPKDB
70 #include <ipkdb/ipkdb.h>
71 #endif
72
73 #if defined(MULTIPROCESSOR)
74 struct simplelock kprintf_slock = SIMPLELOCK_INITIALIZER;
75
76 /*
77 * Use cpu_simple_lock() and cpu_simple_unlock(). These are the actual
78 * atomic locking operations, and never attempt to print debugging
79 * information.
80 */
81 #define KPRINTF_MUTEX_ENTER(s) \
82 do { \
83 (s) = splhigh(); \
84 cpu_simple_lock(&kprintf_slock); \
85 } while (0)
86
87 #define KPRINTF_MUTEX_EXIT(s) \
88 do { \
89 cpu_simple_unlock(&kprintf_slock); \
90 splx((s)); \
91 } while (0)
92 #else /* ! MULTIPROCESSOR */
93 #define KPRINTF_MUTEX_ENTER(s) (s) = splhigh()
94 #define KPRINTF_MUTEX_EXIT(s) splx((s))
95 #endif /* MULTIPROCESSOR */
96
97 /*
98 * note that stdarg.h and the ansi style va_start macro is used for both
99 * ansi and traditional c complers.
100 * XXX: this requires that stdarg.h define: va_alist and va_dcl
101 */
102 #include <machine/stdarg.h>
103
104
105 #ifdef KGDB
106 #include <sys/kgdb.h>
107 #include <machine/cpu.h>
108 #endif
109 #ifdef DDB
110 #include <ddb/db_output.h> /* db_printf, db_putchar prototypes */
111 extern int db_radix; /* XXX: for non-standard '%r' format */
112 #endif
113
114
115 /*
116 * defines
117 */
118
119 /* flags for kprintf */
120 #define TOCONS 0x01 /* to the console */
121 #define TOTTY 0x02 /* to the process' tty */
122 #define TOLOG 0x04 /* to the kernel message buffer */
123 #define TOBUFONLY 0x08 /* to the buffer (only) [for sprintf] */
124 #define TODDB 0x10 /* to ddb console */
125
126 /* max size buffer kprintf needs to print quad_t [size in base 8 + \0] */
127 #define KPRINTF_BUFSIZE (sizeof(quad_t) * NBBY / 3 + 2)
128
129
130 /*
131 * local prototypes
132 */
133
134 static int kprintf __P((const char *, int, void *,
135 char *, va_list));
136 static void putchar __P((int, int, struct tty *));
137 static void klogpri __P((int));
138
139
140 /*
141 * globals
142 */
143
144 struct tty *constty; /* pointer to console "window" tty */
145 extern int log_open; /* subr_log: is /dev/klog open? */
146 const char *panicstr; /* arg to first call to panic (used as a flag
147 to indicate that panic has already been called). */
148
149 /*
150 * v_putc: routine to putc on virtual console
151 *
152 * the v_putc pointer can be used to redirect the console cnputc elsewhere
153 * [e.g. to a "virtual console"].
154 */
155
156 void (*v_putc) __P((int)) = cnputc; /* start with cnputc (normal cons) */
157
158
159 /*
160 * functions
161 */
162
163 /*
164 * tablefull: warn that a system table is full
165 */
166
167 void
168 tablefull(tab)
169 const char *tab;
170 {
171 log(LOG_ERR, "%s: table is full\n", tab);
172 }
173
174 /*
175 * panic: handle an unresolvable fatal error
176 *
177 * prints "panic: <message>" and reboots. if called twice (i.e. recursive
178 * call) we avoid trying to sync the disk and just reboot (to avoid
179 * recursive panics).
180 */
181
182 void
183 #ifdef __STDC__
184 panic(const char *fmt, ...)
185 #else
186 panic(fmt, va_alist)
187 char *fmt;
188 va_dcl
189 #endif
190 {
191 int bootopt;
192 va_list ap;
193
194 bootopt = RB_AUTOBOOT | RB_DUMP;
195 if (panicstr)
196 bootopt |= RB_NOSYNC;
197 else
198 panicstr = fmt;
199
200 va_start(ap, fmt);
201 printf("panic: ");
202 vprintf(fmt, ap);
203 printf("\n");
204 va_end(ap);
205
206 #ifdef IPKDB
207 ipkdb_panic();
208 #endif
209 #ifdef KGDB
210 kgdb_panic();
211 #endif
212 #ifdef KADB
213 if (boothowto & RB_KDB)
214 kdbpanic();
215 #endif
216 #ifdef DDB
217 if (db_onpanic)
218 Debugger();
219 #endif
220 cpu_reboot(bootopt, NULL);
221 }
222
223 /*
224 * kernel logging functions: log, logpri, addlog
225 */
226
227 /*
228 * log: write to the log buffer
229 *
230 * => will not sleep [so safe to call from interrupt]
231 * => will log to console if /dev/klog isn't open
232 */
233
234 void
235 #ifdef __STDC__
236 log(int level, const char *fmt, ...)
237 #else
238 log(level, fmt, va_alist)
239 int level;
240 char *fmt;
241 va_dcl
242 #endif
243 {
244 int s;
245 va_list ap;
246
247 KPRINTF_MUTEX_ENTER(s);
248
249 klogpri(level); /* log the level first */
250 va_start(ap, fmt);
251 kprintf(fmt, TOLOG, NULL, NULL, ap);
252 va_end(ap);
253 if (!log_open) {
254 va_start(ap, fmt);
255 kprintf(fmt, TOCONS, NULL, NULL, ap);
256 va_end(ap);
257 }
258
259 KPRINTF_MUTEX_EXIT(s);
260
261 logwakeup(); /* wake up anyone waiting for log msgs */
262 }
263
264 /*
265 * vlog: write to the log buffer [already have va_alist]
266 */
267
268 void
269 vlog(level, fmt, ap)
270 int level;
271 const char *fmt;
272 va_list ap;
273 {
274 int s;
275
276 KPRINTF_MUTEX_ENTER(s);
277
278 klogpri(level); /* log the level first */
279 kprintf(fmt, TOLOG, NULL, NULL, ap);
280 if (!log_open)
281 kprintf(fmt, TOCONS, NULL, NULL, ap);
282
283 KPRINTF_MUTEX_EXIT(s);
284
285 logwakeup(); /* wake up anyone waiting for log msgs */
286 }
287
288 /*
289 * logpri: log the priority level to the klog
290 */
291
292 void
293 logpri(level)
294 int level;
295 {
296 int s;
297
298 KPRINTF_MUTEX_ENTER(s);
299 klogpri(level);
300 KPRINTF_MUTEX_EXIT(s);
301 }
302
303 /*
304 * Note: we must be in the mutex here!
305 */
306 static void
307 klogpri(level)
308 int level;
309 {
310 char *p;
311 char snbuf[KPRINTF_BUFSIZE];
312
313 putchar('<', TOLOG, NULL);
314 sprintf(snbuf, "%d", level);
315 for (p = snbuf ; *p ; p++)
316 putchar(*p, TOLOG, NULL);
317 putchar('>', TOLOG, NULL);
318 }
319
320 /*
321 * addlog: add info to previous log message
322 */
323
324 void
325 #ifdef __STDC__
326 addlog(const char *fmt, ...)
327 #else
328 addlog(fmt, va_alist)
329 char *fmt;
330 va_dcl
331 #endif
332 {
333 int s;
334 va_list ap;
335
336 KPRINTF_MUTEX_ENTER(s);
337
338 va_start(ap, fmt);
339 kprintf(fmt, TOLOG, NULL, NULL, ap);
340 va_end(ap);
341 if (!log_open) {
342 va_start(ap, fmt);
343 kprintf(fmt, TOCONS, NULL, NULL, ap);
344 va_end(ap);
345 }
346
347 KPRINTF_MUTEX_EXIT(s);
348
349 logwakeup();
350 }
351
352
353 /*
354 * putchar: print a single character on console or user terminal.
355 *
356 * => if console, then the last MSGBUFS chars are saved in msgbuf
357 * for inspection later (e.g. dmesg/syslog)
358 * => we must already be in the mutex!
359 */
360 static void
361 putchar(c, flags, tp)
362 register int c;
363 int flags;
364 struct tty *tp;
365 {
366 register struct kern_msgbuf *mbp;
367
368 if (panicstr)
369 constty = NULL;
370 if ((flags & TOCONS) && tp == NULL && constty) {
371 tp = constty;
372 flags |= TOTTY;
373 }
374 if ((flags & TOTTY) && tp && tputchar(c, tp) < 0 &&
375 (flags & TOCONS) && tp == constty)
376 constty = NULL;
377 if ((flags & TOLOG) &&
378 c != '\0' && c != '\r' && c != 0177 && msgbufenabled) {
379 mbp = msgbufp;
380 if (mbp->msg_magic != MSG_MAGIC) {
381 /*
382 * Arguably should panic or somehow notify the
383 * user... but how? Panic may be too drastic,
384 * and would obliterate the message being kicked
385 * out (maybe a panic itself), and printf
386 * would invoke us recursively. Silently punt
387 * for now. If syslog is running, it should
388 * notice.
389 */
390 msgbufenabled = 0;
391 } else {
392 mbp->msg_bufc[mbp->msg_bufx++] = c;
393 if (mbp->msg_bufx < 0 || mbp->msg_bufx >= mbp->msg_bufs)
394 mbp->msg_bufx = 0;
395 /* If the buffer is full, keep the most recent data. */
396 if (mbp->msg_bufr == mbp->msg_bufx) {
397 if (++mbp->msg_bufr >= mbp->msg_bufs)
398 mbp->msg_bufr = 0;
399 }
400 }
401 }
402 if ((flags & TOCONS) && constty == NULL && c != '\0')
403 (*v_putc)(c);
404 #ifdef DDB
405 if (flags & TODDB)
406 db_putchar(c);
407 #endif
408 }
409
410
411 /*
412 * uprintf: print to the controlling tty of the current process
413 *
414 * => we may block if the tty queue is full
415 * => no message is printed if the queue doesn't clear in a reasonable
416 * time
417 */
418
419 void
420 #ifdef __STDC__
421 uprintf(const char *fmt, ...)
422 #else
423 uprintf(fmt, va_alist)
424 char *fmt;
425 va_dcl
426 #endif
427 {
428 register struct proc *p = curproc;
429 va_list ap;
430
431 if (p->p_flag & P_CONTROLT && p->p_session->s_ttyvp) {
432 /* No mutex needed; going to process TTY. */
433 va_start(ap, fmt);
434 kprintf(fmt, TOTTY, p->p_session->s_ttyp, NULL, ap);
435 va_end(ap);
436 }
437 }
438
439 /*
440 * tprintf functions: used to send messages to a specific process
441 *
442 * usage:
443 * get a tpr_t handle on a process "p" by using "tprintf_open(p)"
444 * use the handle when calling "tprintf"
445 * when done, do a "tprintf_close" to drop the handle
446 */
447
448 /*
449 * tprintf_open: get a tprintf handle on a process "p"
450 *
451 * => returns NULL if process can't be printed to
452 */
453
454 tpr_t
455 tprintf_open(p)
456 register struct proc *p;
457 {
458
459 if (p->p_flag & P_CONTROLT && p->p_session->s_ttyvp) {
460 SESSHOLD(p->p_session);
461 return ((tpr_t) p->p_session);
462 }
463 return ((tpr_t) NULL);
464 }
465
466 /*
467 * tprintf_close: dispose of a tprintf handle obtained with tprintf_open
468 */
469
470 void
471 tprintf_close(sess)
472 tpr_t sess;
473 {
474
475 if (sess)
476 SESSRELE((struct session *) sess);
477 }
478
479 /*
480 * tprintf: given tprintf handle to a process [obtained with tprintf_open],
481 * send a message to the controlling tty for that process.
482 *
483 * => also sends message to /dev/klog
484 */
485 void
486 #ifdef __STDC__
487 tprintf(tpr_t tpr, const char *fmt, ...)
488 #else
489 tprintf(tpr, fmt, va_alist)
490 tpr_t tpr;
491 char *fmt;
492 va_dcl
493 #endif
494 {
495 register struct session *sess = (struct session *)tpr;
496 struct tty *tp = NULL;
497 int s, flags = TOLOG;
498 va_list ap;
499
500 if (sess && sess->s_ttyvp && ttycheckoutq(sess->s_ttyp, 0)) {
501 flags |= TOTTY;
502 tp = sess->s_ttyp;
503 }
504
505 KPRINTF_MUTEX_ENTER(s);
506
507 klogpri(LOG_INFO);
508 va_start(ap, fmt);
509 kprintf(fmt, flags, tp, NULL, ap);
510 va_end(ap);
511
512 KPRINTF_MUTEX_EXIT(s);
513
514 logwakeup();
515 }
516
517
518 /*
519 * ttyprintf: send a message to a specific tty
520 *
521 * => should be used only by tty driver or anything that knows the
522 * underlying tty will not be revoked(2)'d away. [otherwise,
523 * use tprintf]
524 */
525 void
526 #ifdef __STDC__
527 ttyprintf(struct tty *tp, const char *fmt, ...)
528 #else
529 ttyprintf(tp, fmt, va_alist)
530 struct tty *tp;
531 char *fmt;
532 va_dcl
533 #endif
534 {
535 va_list ap;
536
537 /* No mutex needed; going to process TTY. */
538 va_start(ap, fmt);
539 kprintf(fmt, TOTTY, tp, NULL, ap);
540 va_end(ap);
541 }
542
543 #ifdef DDB
544
545 /*
546 * db_printf: printf for DDB (via db_putchar)
547 */
548
549 void
550 #ifdef __STDC__
551 db_printf(const char *fmt, ...)
552 #else
553 db_printf(fmt, va_alist)
554 char *fmt;
555 va_dcl
556 #endif
557 {
558 va_list ap;
559
560 /* No mutex needed; DDB pauses all processors. */
561 va_start(ap, fmt);
562 kprintf(fmt, TODDB, NULL, NULL, ap);
563 va_end(ap);
564 }
565
566 #endif /* DDB */
567
568
569 /*
570 * normal kernel printf functions: printf, vprintf, sprintf
571 */
572
573 /*
574 * printf: print a message to the console and the log
575 */
576 void
577 #ifdef __STDC__
578 printf(const char *fmt, ...)
579 #else
580 printf(fmt, va_alist)
581 char *fmt;
582 va_dcl
583 #endif
584 {
585 va_list ap;
586 int s;
587
588 KPRINTF_MUTEX_ENTER(s);
589
590 va_start(ap, fmt);
591 kprintf(fmt, TOCONS | TOLOG, NULL, NULL, ap);
592 va_end(ap);
593
594 KPRINTF_MUTEX_EXIT(s);
595
596 if (!panicstr)
597 logwakeup();
598 }
599
600 /*
601 * vprintf: print a message to the console and the log [already have
602 * va_alist]
603 */
604
605 void
606 vprintf(fmt, ap)
607 const char *fmt;
608 va_list ap;
609 {
610 int s;
611
612 KPRINTF_MUTEX_ENTER(s);
613
614 kprintf(fmt, TOCONS | TOLOG, NULL, NULL, ap);
615
616 KPRINTF_MUTEX_EXIT(s);
617
618 if (!panicstr)
619 logwakeup();
620 }
621
622 /*
623 * sprintf: print a message to a buffer
624 */
625 int
626 #ifdef __STDC__
627 sprintf(char *buf, const char *fmt, ...)
628 #else
629 sprintf(buf, fmt, va_alist)
630 char *buf;
631 const char *cfmt;
632 va_dcl
633 #endif
634 {
635 int retval;
636 va_list ap;
637
638 va_start(ap, fmt);
639 retval = kprintf(fmt, TOBUFONLY, NULL, buf, ap);
640 va_end(ap);
641 *(buf + retval) = 0; /* null terminate */
642 return(retval);
643 }
644
645 /*
646 * vsprintf: print a message to a buffer [already have va_alist]
647 */
648
649 int
650 vsprintf(buf, fmt, ap)
651 char *buf;
652 const char *fmt;
653 va_list ap;
654 {
655 int retval;
656
657 retval = kprintf(fmt, TOBUFONLY, NULL, buf, ap);
658 *(buf + retval) = 0; /* null terminate */
659 return (retval);
660 }
661
662 /*
663 * snprintf: print a message to a buffer
664 */
665 int
666 #ifdef __STDC__
667 snprintf(char *buf, size_t size, const char *fmt, ...)
668 #else
669 snprintf(buf, size, fmt, va_alist)
670 char *buf;
671 size_t size;
672 const char *cfmt;
673 va_dcl
674 #endif
675 {
676 int retval;
677 va_list ap;
678 char *p;
679
680 if (size < 1)
681 return (-1);
682 p = buf + size - 1;
683 va_start(ap, fmt);
684 retval = kprintf(fmt, TOBUFONLY, &p, buf, ap);
685 va_end(ap);
686 *(p) = 0; /* null terminate */
687 return(retval);
688 }
689
690 /*
691 * vsnprintf: print a message to a buffer [already have va_alist]
692 */
693 int
694 vsnprintf(buf, size, fmt, ap)
695 char *buf;
696 size_t size;
697 const char *fmt;
698 va_list ap;
699 {
700 int retval;
701 char *p;
702
703 if (size < 1)
704 return (-1);
705 p = buf + size - 1;
706 retval = kprintf(fmt, TOBUFONLY, &p, buf, ap);
707 *(p) = 0; /* null terminate */
708 return(retval);
709 }
710
711 /*
712 * bitmask_snprintf: print a kernel-printf "%b" message to a buffer
713 *
714 * => returns pointer to the buffer
715 * => XXX: useful vs. kernel %b?
716 */
717 char *
718 bitmask_snprintf(val, p, buf, buflen)
719 u_quad_t val;
720 const char *p;
721 char *buf;
722 size_t buflen;
723 {
724 char *bp, *q;
725 size_t left;
726 char *sbase, snbuf[KPRINTF_BUFSIZE];
727 int base, bit, ch, len, sep;
728 u_quad_t field;
729
730 bp = buf;
731 memset(buf, 0, buflen);
732
733 /*
734 * Always leave room for the trailing NULL.
735 */
736 left = buflen - 1;
737
738 /*
739 * Print the value into the buffer. Abort if there's not
740 * enough room.
741 */
742 if (buflen < KPRINTF_BUFSIZE)
743 return (buf);
744
745 ch = *p++;
746 base = ch != '\177' ? ch : *p++;
747 sbase = base == 8 ? "%qo" : base == 10 ? "%qd" : base == 16 ? "%qx" : 0;
748 if (sbase == 0)
749 return (buf); /* punt if not oct, dec, or hex */
750
751 sprintf(snbuf, sbase, val);
752 for (q = snbuf ; *q ; q++) {
753 *bp++ = *q;
754 left--;
755 }
756
757 /*
758 * If the value we printed was 0 and we're using the old-style format,
759 * or if we don't have room for "<x>", we're done.
760 */
761 if (((val == 0) && (ch != '\177')) || left < 3)
762 return (buf);
763
764 #define PUTBYTE(b, c, l) \
765 *(b)++ = (c); \
766 if (--(l) == 0) \
767 goto out;
768 #define PUTSTR(b, p, l) do { \
769 int c; \
770 while ((c = *(p)++) != 0) { \
771 *(b)++ = c; \
772 if (--(l) == 0) \
773 goto out; \
774 } \
775 } while (0)
776
777 /*
778 * Chris Torek's new style %b format is identified by a leading \177
779 */
780 sep = '<';
781 if (ch != '\177') {
782 /* old (standard) %b format. */
783 for (;(bit = *p++) != 0;) {
784 if (val & (1 << (bit - 1))) {
785 PUTBYTE(bp, sep, left);
786 for (; (ch = *p) > ' '; ++p) {
787 PUTBYTE(bp, ch, left);
788 }
789 sep = ',';
790 } else
791 for (; *p > ' '; ++p)
792 continue;
793 }
794 } else {
795 /* new quad-capable %b format; also does fields. */
796 field = val;
797 while ((ch = *p++) != '\0') {
798 bit = *p++; /* now 0-origin */
799 switch (ch) {
800 case 'b':
801 if (((u_int)(val >> bit) & 1) == 0)
802 goto skip;
803 PUTBYTE(bp, sep, left);
804 PUTSTR(bp, p, left);
805 sep = ',';
806 break;
807 case 'f':
808 case 'F':
809 len = *p++; /* field length */
810 field = (val >> bit) & ((1ULL << len) - 1);
811 if (ch == 'F') /* just extract */
812 break;
813 PUTBYTE(bp, sep, left);
814 sep = ',';
815 PUTSTR(bp, p, left);
816 PUTBYTE(bp, '=', left);
817 sprintf(snbuf, sbase, field);
818 q = snbuf; PUTSTR(bp, q, left);
819 break;
820 case '=':
821 case ':':
822 /*
823 * Here "bit" is actually a value instead,
824 * to be compared against the last field.
825 * This only works for values in [0..255],
826 * of course.
827 */
828 if ((int)field != bit)
829 goto skip;
830 if (ch == '=')
831 PUTBYTE(bp, '=', left);
832 PUTSTR(bp, p, left);
833 break;
834 default:
835 skip:
836 while (*p++ != '\0')
837 continue;
838 break;
839 }
840 }
841 }
842 if (sep != '<')
843 PUTBYTE(bp, '>', left);
844
845 out:
846 return (buf);
847
848 #undef PUTBYTE
849 #undef PUTSTR
850 }
851
852 /*
853 * kprintf: scaled down version of printf(3).
854 *
855 * this version based on vfprintf() from libc which was derived from
856 * software contributed to Berkeley by Chris Torek.
857 *
858 * Two additional formats:
859 *
860 * The format %b is supported to decode error registers.
861 * Its usage is:
862 *
863 * printf("reg=%b\n", regval, "<base><arg>*");
864 *
865 * where <base> is the output base expressed as a control character, e.g.
866 * \10 gives octal; \20 gives hex. Each arg is a sequence of characters,
867 * the first of which gives the bit number to be inspected (origin 1), and
868 * the next characters (up to a control character, i.e. a character <= 32),
869 * give the name of the register. Thus:
870 *
871 * kprintf("reg=%b\n", 3, "\10\2BITTWO\1BITONE\n");
872 *
873 * would produce output:
874 *
875 * reg=3<BITTWO,BITONE>
876 *
877 * The format %: passes an additional format string and argument list
878 * recursively. Its usage is:
879 *
880 * fn(char *fmt, ...)
881 * {
882 * va_list ap;
883 * va_start(ap, fmt);
884 * printf("prefix: %: suffix\n", fmt, ap);
885 * va_end(ap);
886 * }
887 *
888 * this is the actual printf innards
889 *
890 * This code is large and complicated...
891 *
892 * NOTE: The kprintf mutex must be held of we're going TOBUF or TOCONS!
893 */
894
895 /*
896 * macros for converting digits to letters and vice versa
897 */
898 #define to_digit(c) ((c) - '0')
899 #define is_digit(c) ((unsigned)to_digit(c) <= 9)
900 #define to_char(n) ((n) + '0')
901
902 /*
903 * flags used during conversion.
904 */
905 #define ALT 0x001 /* alternate form */
906 #define HEXPREFIX 0x002 /* add 0x or 0X prefix */
907 #define LADJUST 0x004 /* left adjustment */
908 #define LONGDBL 0x008 /* long double; unimplemented */
909 #define LONGINT 0x010 /* long integer */
910 #define QUADINT 0x020 /* quad integer */
911 #define SHORTINT 0x040 /* short integer */
912 #define ZEROPAD 0x080 /* zero (as opposed to blank) pad */
913 #define FPT 0x100 /* Floating point number */
914
915 /*
916 * To extend shorts properly, we need both signed and unsigned
917 * argument extraction methods.
918 */
919 #define SARG() \
920 (flags&QUADINT ? va_arg(ap, quad_t) : \
921 flags&LONGINT ? va_arg(ap, long) : \
922 flags&SHORTINT ? (long)(short)va_arg(ap, int) : \
923 (long)va_arg(ap, int))
924 #define UARG() \
925 (flags&QUADINT ? va_arg(ap, u_quad_t) : \
926 flags&LONGINT ? va_arg(ap, u_long) : \
927 flags&SHORTINT ? (u_long)(u_short)va_arg(ap, int) : \
928 (u_long)va_arg(ap, u_int))
929
930 #define KPRINTF_PUTCHAR(C) { \
931 if (oflags == TOBUFONLY) { \
932 if ((vp != NULL) && (sbuf == tailp)) { \
933 ret += 1; /* indicate error */ \
934 goto overflow; \
935 } \
936 *sbuf++ = (C); \
937 } else { \
938 putchar((C), oflags, (struct tty *)vp); \
939 } \
940 }
941
942 /*
943 * Guts of kernel printf. Note, we already expect to be in a mutex!
944 */
945 static int
946 kprintf(fmt0, oflags, vp, sbuf, ap)
947 const char *fmt0;
948 int oflags;
949 void *vp;
950 char *sbuf;
951 va_list ap;
952 {
953 char *fmt; /* format string */
954 int ch; /* character from fmt */
955 int n; /* handy integer (short term usage) */
956 char *cp; /* handy char pointer (short term usage) */
957 int flags; /* flags as above */
958 int ret; /* return value accumulator */
959 int width; /* width from format (%8d), or 0 */
960 int prec; /* precision from format (%.3d), or -1 */
961 char sign; /* sign prefix (' ', '+', '-', or \0) */
962
963 u_quad_t _uquad; /* integer arguments %[diouxX] */
964 enum { OCT, DEC, HEX } base;/* base for [diouxX] conversion */
965 int dprec; /* a copy of prec if [diouxX], 0 otherwise */
966 int realsz; /* field size expanded by dprec */
967 int size; /* size of converted field or string */
968 char *xdigs; /* digits for [xX] conversion */
969 char buf[KPRINTF_BUFSIZE]; /* space for %c, %[diouxX] */
970 char *tailp; /* tail pointer for snprintf */
971
972 tailp = NULL; /* XXX: shutup gcc */
973 if (oflags == TOBUFONLY && (vp != NULL))
974 tailp = *(char **)vp;
975
976 cp = NULL; /* XXX: shutup gcc */
977 size = 0; /* XXX: shutup gcc */
978
979 fmt = (char *)fmt0;
980 ret = 0;
981
982 xdigs = NULL; /* XXX: shut up gcc warning */
983
984 /*
985 * Scan the format for conversions (`%' character).
986 */
987 for (;;) {
988 while (*fmt != '%' && *fmt) {
989 ret++;
990 KPRINTF_PUTCHAR(*fmt++);
991 }
992 if (*fmt == 0)
993 goto done;
994
995 fmt++; /* skip over '%' */
996
997 flags = 0;
998 dprec = 0;
999 width = 0;
1000 prec = -1;
1001 sign = '\0';
1002
1003 rflag: ch = *fmt++;
1004 reswitch: switch (ch) {
1005 /* XXX: non-standard '%:' format */
1006 #ifndef __powerpc__
1007 case ':':
1008 if (oflags != TOBUFONLY) {
1009 cp = va_arg(ap, char *);
1010 kprintf(cp, oflags, vp,
1011 NULL, va_arg(ap, va_list));
1012 }
1013 continue; /* no output */
1014 #endif
1015 /* XXX: non-standard '%b' format */
1016 case 'b': {
1017 char *b, *z;
1018 int tmp;
1019 _uquad = va_arg(ap, int);
1020 b = va_arg(ap, char *);
1021 if (*b == 8)
1022 sprintf(buf, "%qo", (unsigned long long)_uquad);
1023 else if (*b == 10)
1024 sprintf(buf, "%qd", (unsigned long long)_uquad);
1025 else if (*b == 16)
1026 sprintf(buf, "%qx", (unsigned long long)_uquad);
1027 else
1028 break;
1029 b++;
1030
1031 z = buf;
1032 while (*z) {
1033 ret++;
1034 KPRINTF_PUTCHAR(*z++);
1035 }
1036
1037 if (_uquad) {
1038 tmp = 0;
1039 while ((n = *b++) != 0) {
1040 if (_uquad & (1 << (n - 1))) {
1041 ret++;
1042 KPRINTF_PUTCHAR(tmp ? ',':'<');
1043 while ((n = *b) > ' ') {
1044 ret++;
1045 KPRINTF_PUTCHAR(n);
1046 b++;
1047 }
1048 tmp = 1;
1049 } else {
1050 while(*b > ' ')
1051 b++;
1052 }
1053 }
1054 if (tmp) {
1055 ret++;
1056 KPRINTF_PUTCHAR('>');
1057 }
1058 }
1059 continue; /* no output */
1060 }
1061
1062 #ifdef DDB
1063 /* XXX: non-standard '%r' format (print int in db_radix) */
1064 case 'r':
1065 if ((oflags & TODDB) == 0)
1066 goto default_case;
1067
1068 if (db_radix == 16)
1069 goto case_z; /* signed hex */
1070 _uquad = SARG();
1071 if ((quad_t)_uquad < 0) {
1072 _uquad = -_uquad;
1073 sign = '-';
1074 }
1075 base = (db_radix == 8) ? OCT : DEC;
1076 goto number;
1077
1078
1079 /* XXX: non-standard '%z' format ("signed hex", a "hex %i")*/
1080 case 'z':
1081 case_z:
1082 if ((oflags & TODDB) == 0)
1083 goto default_case;
1084
1085 xdigs = "0123456789abcdef";
1086 ch = 'x'; /* the 'x' in '0x' (below) */
1087 _uquad = SARG();
1088 base = HEX;
1089 /* leading 0x/X only if non-zero */
1090 if (flags & ALT && _uquad != 0)
1091 flags |= HEXPREFIX;
1092 if ((quad_t)_uquad < 0) {
1093 _uquad = -_uquad;
1094 sign = '-';
1095 }
1096 goto number;
1097 #endif
1098
1099 case ' ':
1100 /*
1101 * ``If the space and + flags both appear, the space
1102 * flag will be ignored.''
1103 * -- ANSI X3J11
1104 */
1105 if (!sign)
1106 sign = ' ';
1107 goto rflag;
1108 case '#':
1109 flags |= ALT;
1110 goto rflag;
1111 case '*':
1112 /*
1113 * ``A negative field width argument is taken as a
1114 * - flag followed by a positive field width.''
1115 * -- ANSI X3J11
1116 * They don't exclude field widths read from args.
1117 */
1118 if ((width = va_arg(ap, int)) >= 0)
1119 goto rflag;
1120 width = -width;
1121 /* FALLTHROUGH */
1122 case '-':
1123 flags |= LADJUST;
1124 goto rflag;
1125 case '+':
1126 sign = '+';
1127 goto rflag;
1128 case '.':
1129 if ((ch = *fmt++) == '*') {
1130 n = va_arg(ap, int);
1131 prec = n < 0 ? -1 : n;
1132 goto rflag;
1133 }
1134 n = 0;
1135 while (is_digit(ch)) {
1136 n = 10 * n + to_digit(ch);
1137 ch = *fmt++;
1138 }
1139 prec = n < 0 ? -1 : n;
1140 goto reswitch;
1141 case '0':
1142 /*
1143 * ``Note that 0 is taken as a flag, not as the
1144 * beginning of a field width.''
1145 * -- ANSI X3J11
1146 */
1147 flags |= ZEROPAD;
1148 goto rflag;
1149 case '1': case '2': case '3': case '4':
1150 case '5': case '6': case '7': case '8': case '9':
1151 n = 0;
1152 do {
1153 n = 10 * n + to_digit(ch);
1154 ch = *fmt++;
1155 } while (is_digit(ch));
1156 width = n;
1157 goto reswitch;
1158 case 'h':
1159 flags |= SHORTINT;
1160 goto rflag;
1161 case 'l':
1162 if (*fmt == 'l') {
1163 fmt++;
1164 flags |= QUADINT;
1165 } else {
1166 flags |= LONGINT;
1167 }
1168 goto rflag;
1169 case 'q':
1170 flags |= QUADINT;
1171 goto rflag;
1172 case 'c':
1173 *(cp = buf) = va_arg(ap, int);
1174 size = 1;
1175 sign = '\0';
1176 break;
1177 case 'D':
1178 flags |= LONGINT;
1179 /*FALLTHROUGH*/
1180 case 'd':
1181 case 'i':
1182 _uquad = SARG();
1183 if ((quad_t)_uquad < 0) {
1184 _uquad = -_uquad;
1185 sign = '-';
1186 }
1187 base = DEC;
1188 goto number;
1189 case 'n':
1190 #ifdef DDB
1191 /* XXX: non-standard '%n' format */
1192 /*
1193 * XXX: HACK! DDB wants '%n' to be a '%u' printed
1194 * in db_radix format. this should die since '%n'
1195 * is already defined in standard printf to write
1196 * the number of chars printed so far to the arg (which
1197 * should be a pointer.
1198 */
1199 if (oflags & TODDB) {
1200 if (db_radix == 16)
1201 ch = 'x'; /* convert to %x */
1202 else if (db_radix == 8)
1203 ch = 'o'; /* convert to %o */
1204 else
1205 ch = 'u'; /* convert to %u */
1206
1207 /* ... and start again */
1208 goto reswitch;
1209 }
1210
1211 #endif
1212 if (flags & QUADINT)
1213 *va_arg(ap, quad_t *) = ret;
1214 else if (flags & LONGINT)
1215 *va_arg(ap, long *) = ret;
1216 else if (flags & SHORTINT)
1217 *va_arg(ap, short *) = ret;
1218 else
1219 *va_arg(ap, int *) = ret;
1220 continue; /* no output */
1221 case 'O':
1222 flags |= LONGINT;
1223 /*FALLTHROUGH*/
1224 case 'o':
1225 _uquad = UARG();
1226 base = OCT;
1227 goto nosign;
1228 case 'p':
1229 /*
1230 * ``The argument shall be a pointer to void. The
1231 * value of the pointer is converted to a sequence
1232 * of printable characters, in an implementation-
1233 * defined manner.''
1234 * -- ANSI X3J11
1235 */
1236 /* NOSTRICT */
1237 _uquad = (u_long)va_arg(ap, void *);
1238 base = HEX;
1239 xdigs = "0123456789abcdef";
1240 flags |= HEXPREFIX;
1241 ch = 'x';
1242 goto nosign;
1243 case 's':
1244 if ((cp = va_arg(ap, char *)) == NULL)
1245 cp = "(null)";
1246 if (prec >= 0) {
1247 /*
1248 * can't use strlen; can only look for the
1249 * NUL in the first `prec' characters, and
1250 * strlen() will go further.
1251 */
1252 char *p = memchr(cp, 0, prec);
1253
1254 if (p != NULL) {
1255 size = p - cp;
1256 if (size > prec)
1257 size = prec;
1258 } else
1259 size = prec;
1260 } else
1261 size = strlen(cp);
1262 sign = '\0';
1263 break;
1264 case 'U':
1265 flags |= LONGINT;
1266 /*FALLTHROUGH*/
1267 case 'u':
1268 _uquad = UARG();
1269 base = DEC;
1270 goto nosign;
1271 case 'X':
1272 xdigs = "0123456789ABCDEF";
1273 goto hex;
1274 case 'x':
1275 xdigs = "0123456789abcdef";
1276 hex: _uquad = UARG();
1277 base = HEX;
1278 /* leading 0x/X only if non-zero */
1279 if (flags & ALT && _uquad != 0)
1280 flags |= HEXPREFIX;
1281
1282 /* unsigned conversions */
1283 nosign: sign = '\0';
1284 /*
1285 * ``... diouXx conversions ... if a precision is
1286 * specified, the 0 flag will be ignored.''
1287 * -- ANSI X3J11
1288 */
1289 number: if ((dprec = prec) >= 0)
1290 flags &= ~ZEROPAD;
1291
1292 /*
1293 * ``The result of converting a zero value with an
1294 * explicit precision of zero is no characters.''
1295 * -- ANSI X3J11
1296 */
1297 cp = buf + KPRINTF_BUFSIZE;
1298 if (_uquad != 0 || prec != 0) {
1299 /*
1300 * Unsigned mod is hard, and unsigned mod
1301 * by a constant is easier than that by
1302 * a variable; hence this switch.
1303 */
1304 switch (base) {
1305 case OCT:
1306 do {
1307 *--cp = to_char(_uquad & 7);
1308 _uquad >>= 3;
1309 } while (_uquad);
1310 /* handle octal leading 0 */
1311 if (flags & ALT && *cp != '0')
1312 *--cp = '0';
1313 break;
1314
1315 case DEC:
1316 /* many numbers are 1 digit */
1317 while (_uquad >= 10) {
1318 *--cp = to_char(_uquad % 10);
1319 _uquad /= 10;
1320 }
1321 *--cp = to_char(_uquad);
1322 break;
1323
1324 case HEX:
1325 do {
1326 *--cp = xdigs[_uquad & 15];
1327 _uquad >>= 4;
1328 } while (_uquad);
1329 break;
1330
1331 default:
1332 cp = "bug in kprintf: bad base";
1333 size = strlen(cp);
1334 goto skipsize;
1335 }
1336 }
1337 size = buf + KPRINTF_BUFSIZE - cp;
1338 skipsize:
1339 break;
1340 default: /* "%?" prints ?, unless ? is NUL */
1341 #ifdef DDB
1342 default_case: /* DDB */
1343 #endif
1344 if (ch == '\0')
1345 goto done;
1346 /* pretend it was %c with argument ch */
1347 cp = buf;
1348 *cp = ch;
1349 size = 1;
1350 sign = '\0';
1351 break;
1352 }
1353
1354 /*
1355 * All reasonable formats wind up here. At this point, `cp'
1356 * points to a string which (if not flags&LADJUST) should be
1357 * padded out to `width' places. If flags&ZEROPAD, it should
1358 * first be prefixed by any sign or other prefix; otherwise,
1359 * it should be blank padded before the prefix is emitted.
1360 * After any left-hand padding and prefixing, emit zeroes
1361 * required by a decimal [diouxX] precision, then print the
1362 * string proper, then emit zeroes required by any leftover
1363 * floating precision; finally, if LADJUST, pad with blanks.
1364 *
1365 * Compute actual size, so we know how much to pad.
1366 * size excludes decimal prec; realsz includes it.
1367 */
1368 realsz = dprec > size ? dprec : size;
1369 if (sign)
1370 realsz++;
1371 else if (flags & HEXPREFIX)
1372 realsz+= 2;
1373
1374 /* adjust ret */
1375 ret += width > realsz ? width : realsz;
1376
1377 /* right-adjusting blank padding */
1378 if ((flags & (LADJUST|ZEROPAD)) == 0) {
1379 n = width - realsz;
1380 while (n-- > 0)
1381 KPRINTF_PUTCHAR(' ');
1382 }
1383
1384 /* prefix */
1385 if (sign) {
1386 KPRINTF_PUTCHAR(sign);
1387 } else if (flags & HEXPREFIX) {
1388 KPRINTF_PUTCHAR('0');
1389 KPRINTF_PUTCHAR(ch);
1390 }
1391
1392 /* right-adjusting zero padding */
1393 if ((flags & (LADJUST|ZEROPAD)) == ZEROPAD) {
1394 n = width - realsz;
1395 while (n-- > 0)
1396 KPRINTF_PUTCHAR('0');
1397 }
1398
1399 /* leading zeroes from decimal precision */
1400 n = dprec - size;
1401 while (n-- > 0)
1402 KPRINTF_PUTCHAR('0');
1403
1404 /* the string or number proper */
1405 while (size--)
1406 KPRINTF_PUTCHAR(*cp++);
1407 /* left-adjusting padding (always blank) */
1408 if (flags & LADJUST) {
1409 n = width - realsz;
1410 while (n-- > 0)
1411 KPRINTF_PUTCHAR(' ');
1412 }
1413 }
1414
1415 done:
1416 if ((oflags == TOBUFONLY) && (vp != NULL))
1417 *(char **)vp = sbuf;
1418 overflow:
1419 return (ret);
1420 /* NOTREACHED */
1421 }
1422