Line data Source code
1 : /* $OpenBSD: subr_prf.c,v 1.95 2018/04/10 09:24:56 mpi Exp $ */
2 : /* $NetBSD: subr_prf.c,v 1.45 1997/10/24 18:14:25 chuck Exp $ */
3 :
4 : /*-
5 : * Copyright (c) 1986, 1988, 1991, 1993
6 : * The Regents of the University of California. All rights reserved.
7 : * (c) UNIX System Laboratories, Inc.
8 : * All or some portions of this file are derived from material licensed
9 : * to the University of California by American Telephone and Telegraph
10 : * Co. or Unix System Laboratories, Inc. and are reproduced herein with
11 : * the permission of UNIX System Laboratories, Inc.
12 : *
13 : * Redistribution and use in source and binary forms, with or without
14 : * modification, are permitted provided that the following conditions
15 : * are met:
16 : * 1. Redistributions of source code must retain the above copyright
17 : * notice, this list of conditions and the following disclaimer.
18 : * 2. Redistributions in binary form must reproduce the above copyright
19 : * notice, this list of conditions and the following disclaimer in the
20 : * documentation and/or other materials provided with the distribution.
21 : * 3. Neither the name of the University nor the names of its contributors
22 : * may be used to endorse or promote products derived from this software
23 : * without specific prior written permission.
24 : *
25 : * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26 : * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 : * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 : * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29 : * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30 : * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31 : * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 : * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 : * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34 : * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 : * SUCH DAMAGE.
36 : *
37 : * @(#)subr_prf.c 8.3 (Berkeley) 1/21/94
38 : */
39 :
40 : #include <sys/param.h>
41 : #include <sys/systm.h>
42 : #include <sys/conf.h>
43 : #include <sys/reboot.h>
44 : #include <sys/msgbuf.h>
45 : #include <sys/proc.h>
46 : #include <sys/ioctl.h>
47 : #include <sys/vnode.h>
48 : #include <sys/tty.h>
49 : #include <sys/tprintf.h>
50 : #include <sys/syslog.h>
51 : #include <sys/malloc.h>
52 : #include <sys/pool.h>
53 : #include <sys/mutex.h>
54 :
55 : #include <dev/cons.h>
56 :
57 : /*
58 : * note that stdarg.h and the ansi style va_start macro is used for both
59 : * ansi and traditional c compilers.
60 : */
61 : #include <sys/stdarg.h>
62 :
63 : #ifdef DDB
64 : #include <ddb/db_output.h> /* db_printf, db_putchar prototypes */
65 : #include <ddb/db_var.h> /* db_log, db_radix */
66 : #endif
67 :
68 :
69 : /*
70 : * defines
71 : */
72 :
73 : /* flags for kprintf */
74 : #define TOCONS 0x01 /* to the console */
75 : #define TOTTY 0x02 /* to the process' tty */
76 : #define TOLOG 0x04 /* to the kernel message buffer */
77 : #define TOBUFONLY 0x08 /* to the buffer (only) [for snprintf] */
78 : #define TODDB 0x10 /* to ddb console */
79 : #define TOCOUNT 0x20 /* act like [v]snprintf */
80 :
81 : /* max size buffer kprintf needs to print quad_t [size in base 8 + \0] */
82 : #define KPRINTF_BUFSIZE (sizeof(quad_t) * NBBY / 3 + 2)
83 :
84 :
85 : /*
86 : * local prototypes
87 : */
88 :
89 : int kprintf(const char *, int, void *, char *, va_list);
90 : void kputchar(int, int, struct tty *);
91 :
92 : struct mutex kprintf_mutex =
93 : MUTEX_INITIALIZER_FLAGS(IPL_HIGH, "kprintf", MTX_NOWITNESS);
94 :
95 : /*
96 : * globals
97 : */
98 :
99 : extern int log_open; /* subr_log: is /dev/klog open? */
100 : const char *panicstr; /* arg to first call to panic (used as a flag
101 : to indicate that panic has already been called). */
102 : const char *faultstr; /* page fault string */
103 : #ifdef DDB
104 : /*
105 : * Enter ddb on panic.
106 : */
107 : int db_panic = 1;
108 :
109 : /*
110 : * db_console controls if we can be able to enter ddb by a special key
111 : * combination (machine dependent).
112 : * If DDB_SAFE_CONSOLE is defined in the kernel configuration it allows
113 : * to break into console during boot. It's _really_ useful when debugging
114 : * some things in the kernel that can cause init(8) to crash.
115 : */
116 : #ifdef DDB_SAFE_CONSOLE
117 : int db_console = 1;
118 : #else
119 : int db_console = 0;
120 : #endif
121 :
122 : /*
123 : * flag to indicate if we are currently in ddb (on some processor)
124 : */
125 : int db_is_active;
126 : #endif
127 :
128 : /*
129 : * panic on spl assertion failure?
130 : */
131 : int splassert_ctl = 1;
132 :
133 : /*
134 : * v_putc: routine to putc on virtual console
135 : *
136 : * the v_putc pointer can be used to redirect the console cnputc elsewhere
137 : * [e.g. to a "virtual console"].
138 : */
139 :
140 : void (*v_putc)(int) = cnputc; /* start with cnputc (normal cons) */
141 :
142 :
143 : /*
144 : * functions
145 : */
146 :
147 : /*
148 : * Partial support (the failure case) of the assertion facility
149 : * commonly found in userland.
150 : */
151 : void
152 0 : __assert(const char *t, const char *f, int l, const char *e)
153 : {
154 :
155 0 : panic(__KASSERTSTR, t, e, f, l);
156 : }
157 :
158 : /*
159 : * tablefull: warn that a system table is full
160 : */
161 :
162 : void
163 0 : tablefull(const char *tab)
164 : {
165 0 : log(LOG_ERR, "%s: table is full\n", tab);
166 0 : }
167 :
168 : /*
169 : * panic: handle an unresolvable fatal error
170 : *
171 : * prints "panic: <message>" and reboots. if called twice (i.e. recursive
172 : * call) we avoid trying to sync the disk and just reboot (to avoid
173 : * recursive panics).
174 : */
175 :
176 : void
177 0 : panic(const char *fmt, ...)
178 : {
179 : static char panicbuf[512];
180 : int bootopt;
181 0 : va_list ap;
182 :
183 : /* do not trigger assertions, we know that we are inconsistent */
184 0 : splassert_ctl = 0;
185 :
186 : bootopt = RB_AUTOBOOT | RB_DUMP;
187 0 : va_start(ap, fmt);
188 0 : if (panicstr)
189 0 : bootopt |= RB_NOSYNC;
190 : else {
191 0 : vsnprintf(panicbuf, sizeof panicbuf, fmt, ap);
192 0 : panicstr = panicbuf;
193 : }
194 0 : va_end(ap);
195 :
196 0 : printf("panic: ");
197 0 : va_start(ap, fmt);
198 0 : vprintf(fmt, ap);
199 0 : printf("\n");
200 0 : va_end(ap);
201 :
202 : #ifdef DDB
203 0 : if (db_panic)
204 0 : db_enter();
205 : else
206 0 : db_stack_dump();
207 : #endif
208 0 : reboot(bootopt);
209 : /* NOTREACHED */
210 : }
211 :
212 : /*
213 : * We print only the function name. The file name is usually very long and
214 : * would eat tons of space in the kernel.
215 : */
216 : void
217 0 : splassert_fail(int wantipl, int haveipl, const char *func)
218 : {
219 0 : if (panicstr || db_active)
220 : return;
221 :
222 0 : printf("splassert: %s: want %d have %d\n", func, wantipl, haveipl);
223 0 : switch (splassert_ctl) {
224 : case 1:
225 : break;
226 : case 2:
227 : #ifdef DDB
228 0 : db_stack_dump();
229 : #endif
230 0 : break;
231 : case 3:
232 : #ifdef DDB
233 0 : db_stack_dump();
234 0 : db_enter();
235 : #endif
236 0 : break;
237 : default:
238 0 : panic("spl assertion failure in %s", func);
239 : }
240 0 : }
241 :
242 : /*
243 : * kernel logging functions: log, logpri, addlog
244 : */
245 :
246 : /*
247 : * log: write to the log buffer
248 : *
249 : * => will not sleep [so safe to call from interrupt]
250 : * => will log to console if /dev/klog isn't open
251 : */
252 :
253 : void
254 0 : log(int level, const char *fmt, ...)
255 : {
256 : int s;
257 0 : va_list ap;
258 :
259 0 : s = splhigh();
260 0 : logpri(level); /* log the level first */
261 0 : va_start(ap, fmt);
262 0 : kprintf(fmt, TOLOG, NULL, NULL, ap);
263 0 : va_end(ap);
264 0 : splx(s);
265 0 : if (!log_open) {
266 0 : va_start(ap, fmt);
267 0 : mtx_enter(&kprintf_mutex);
268 0 : kprintf(fmt, TOCONS, NULL, NULL, ap);
269 0 : mtx_leave(&kprintf_mutex);
270 0 : va_end(ap);
271 0 : }
272 0 : logwakeup(); /* wake up anyone waiting for log msgs */
273 0 : }
274 :
275 : /*
276 : * logpri: log the priority level to the klog
277 : */
278 :
279 : void
280 0 : logpri(int level)
281 : {
282 : char *p;
283 0 : char snbuf[KPRINTF_BUFSIZE];
284 :
285 0 : kputchar('<', TOLOG, NULL);
286 0 : snprintf(snbuf, sizeof snbuf, "%d", level);
287 0 : for (p = snbuf ; *p ; p++)
288 0 : kputchar(*p, TOLOG, NULL);
289 0 : kputchar('>', TOLOG, NULL);
290 0 : }
291 :
292 : /*
293 : * addlog: add info to previous log message
294 : */
295 :
296 : int
297 0 : addlog(const char *fmt, ...)
298 : {
299 : int s;
300 0 : va_list ap;
301 :
302 0 : s = splhigh();
303 0 : va_start(ap, fmt);
304 0 : kprintf(fmt, TOLOG, NULL, NULL, ap);
305 0 : va_end(ap);
306 0 : splx(s);
307 0 : if (!log_open) {
308 0 : va_start(ap, fmt);
309 0 : mtx_enter(&kprintf_mutex);
310 0 : kprintf(fmt, TOCONS, NULL, NULL, ap);
311 0 : mtx_leave(&kprintf_mutex);
312 0 : va_end(ap);
313 0 : }
314 0 : logwakeup();
315 0 : return(0);
316 0 : }
317 :
318 :
319 : /*
320 : * kputchar: print a single character on console or user terminal.
321 : *
322 : * => if console, then the last MSGBUFS chars are saved in msgbuf
323 : * for inspection later (e.g. dmesg/syslog)
324 : */
325 : void
326 0 : kputchar(int c, int flags, struct tty *tp)
327 : {
328 : extern int msgbufmapped;
329 : int ddb_active = 0;
330 :
331 : #ifdef DDB
332 0 : ddb_active = db_is_active;
333 : #endif
334 :
335 0 : if (panicstr)
336 0 : constty = NULL;
337 :
338 0 : if ((flags & TOCONS) && tp == NULL && constty && !ddb_active) {
339 : tp = constty;
340 0 : flags |= TOTTY;
341 0 : }
342 0 : if ((flags & TOTTY) && tp && tputchar(c, tp) < 0 &&
343 0 : (flags & TOCONS) && tp == constty)
344 0 : constty = NULL;
345 0 : if ((flags & TOLOG) &&
346 0 : c != '\0' && c != '\r' && c != 0177 && msgbufmapped)
347 0 : msgbuf_putchar(msgbufp, c);
348 0 : if ((flags & TOCONS) && (constty == NULL || ddb_active) && c != '\0')
349 0 : (*v_putc)(c);
350 : #ifdef DDB
351 0 : if (flags & TODDB)
352 0 : db_putchar(c);
353 : #endif
354 0 : }
355 :
356 :
357 : /*
358 : * uprintf: print to the controlling tty of the current process
359 : *
360 : * => we may block if the tty queue is full
361 : * => no message is printed if the queue doesn't clear in a reasonable
362 : * time
363 : */
364 :
365 : void
366 0 : uprintf(const char *fmt, ...)
367 : {
368 0 : struct process *pr = curproc->p_p;
369 0 : va_list ap;
370 :
371 0 : if (pr->ps_flags & PS_CONTROLT && pr->ps_session->s_ttyvp) {
372 0 : va_start(ap, fmt);
373 0 : kprintf(fmt, TOTTY, pr->ps_session->s_ttyp, NULL, ap);
374 0 : va_end(ap);
375 0 : }
376 0 : }
377 :
378 : #if defined(NFSSERVER) || defined(NFSCLIENT)
379 :
380 : /*
381 : * tprintf functions: used to send messages to a specific process
382 : *
383 : * usage:
384 : * get a tpr_t handle on a process "p" by using "tprintf_open(p)"
385 : * use the handle when calling "tprintf"
386 : * when done, do a "tprintf_close" to drop the handle
387 : */
388 :
389 : /*
390 : * tprintf_open: get a tprintf handle on a process "p"
391 : * XXX change s/proc/process
392 : *
393 : * => returns NULL if process can't be printed to
394 : */
395 :
396 : tpr_t
397 0 : tprintf_open(struct proc *p)
398 : {
399 0 : struct process *pr = p->p_p;
400 :
401 0 : if (pr->ps_flags & PS_CONTROLT && pr->ps_session->s_ttyvp) {
402 0 : SESSHOLD(pr->ps_session);
403 0 : return ((tpr_t)pr->ps_session);
404 : }
405 0 : return ((tpr_t) NULL);
406 0 : }
407 :
408 : /*
409 : * tprintf_close: dispose of a tprintf handle obtained with tprintf_open
410 : */
411 :
412 : void
413 0 : tprintf_close(tpr_t sess)
414 : {
415 :
416 0 : if (sess)
417 0 : SESSRELE((struct session *) sess);
418 0 : }
419 :
420 : /*
421 : * tprintf: given tprintf handle to a process [obtained with tprintf_open],
422 : * send a message to the controlling tty for that process.
423 : *
424 : * => also sends message to /dev/klog
425 : */
426 : void
427 0 : tprintf(tpr_t tpr, const char *fmt, ...)
428 : {
429 : struct session *sess = (struct session *)tpr;
430 : struct tty *tp = NULL;
431 : int flags = TOLOG;
432 0 : va_list ap;
433 :
434 0 : logpri(LOG_INFO);
435 0 : if (sess && sess->s_ttyvp && ttycheckoutq(sess->s_ttyp, 0)) {
436 : flags |= TOTTY;
437 0 : tp = sess->s_ttyp;
438 0 : }
439 0 : va_start(ap, fmt);
440 0 : kprintf(fmt, flags, tp, NULL, ap);
441 0 : va_end(ap);
442 0 : logwakeup();
443 0 : }
444 :
445 : #endif /* NFSSERVER || NFSCLIENT */
446 :
447 :
448 : /*
449 : * ttyprintf: send a message to a specific tty
450 : *
451 : * => should be used only by tty driver or anything that knows the
452 : * underlying tty will not be revoked(2)'d away. [otherwise,
453 : * use tprintf]
454 : */
455 : void
456 0 : ttyprintf(struct tty *tp, const char *fmt, ...)
457 : {
458 0 : va_list ap;
459 :
460 0 : va_start(ap, fmt);
461 0 : kprintf(fmt, TOTTY, tp, NULL, ap);
462 0 : va_end(ap);
463 0 : }
464 :
465 : #ifdef DDB
466 :
467 : /*
468 : * db_printf: printf for DDB (via db_putchar)
469 : */
470 :
471 : int
472 0 : db_printf(const char *fmt, ...)
473 : {
474 0 : va_list ap;
475 : int retval;
476 :
477 0 : va_start(ap, fmt);
478 0 : retval = db_vprintf(fmt, ap);
479 0 : va_end(ap);
480 0 : return(retval);
481 0 : }
482 :
483 : int
484 0 : db_vprintf(const char *fmt, va_list ap)
485 : {
486 : int flags;
487 :
488 : flags = TODDB;
489 0 : if (db_log)
490 0 : flags |= TOLOG;
491 0 : return (kprintf(fmt, flags, NULL, NULL, ap));
492 : }
493 : #endif /* DDB */
494 :
495 :
496 : /*
497 : * normal kernel printf functions: printf, vprintf, snprintf
498 : */
499 :
500 : /*
501 : * printf: print a message to the console and the log
502 : */
503 : int
504 0 : printf(const char *fmt, ...)
505 : {
506 0 : va_list ap;
507 : int retval;
508 :
509 :
510 0 : va_start(ap, fmt);
511 0 : mtx_enter(&kprintf_mutex);
512 0 : retval = kprintf(fmt, TOCONS | TOLOG, NULL, NULL, ap);
513 0 : mtx_leave(&kprintf_mutex);
514 0 : va_end(ap);
515 0 : if (!panicstr)
516 0 : logwakeup();
517 :
518 :
519 0 : return(retval);
520 0 : }
521 :
522 : /*
523 : * vprintf: print a message to the console and the log [already have a
524 : * va_list]
525 : */
526 :
527 : int
528 0 : vprintf(const char *fmt, va_list ap)
529 : {
530 : int retval;
531 :
532 0 : mtx_enter(&kprintf_mutex);
533 0 : retval = kprintf(fmt, TOCONS | TOLOG, NULL, NULL, ap);
534 0 : mtx_leave(&kprintf_mutex);
535 0 : if (!panicstr)
536 0 : logwakeup();
537 :
538 :
539 0 : return (retval);
540 : }
541 :
542 : /*
543 : * snprintf: print a message to a buffer
544 : */
545 : int
546 0 : snprintf(char *buf, size_t size, const char *fmt, ...)
547 : {
548 : int retval;
549 0 : va_list ap;
550 0 : char *p;
551 :
552 0 : p = buf + size - 1;
553 0 : if (size < 1)
554 0 : p = buf;
555 0 : va_start(ap, fmt);
556 0 : retval = kprintf(fmt, TOBUFONLY | TOCOUNT, &p, buf, ap);
557 0 : va_end(ap);
558 0 : if (size > 0)
559 0 : *(p) = 0; /* null terminate */
560 0 : return(retval);
561 0 : }
562 :
563 : /*
564 : * vsnprintf: print a message to a buffer [already have va_alist]
565 : */
566 : int
567 0 : vsnprintf(char *buf, size_t size, const char *fmt, va_list ap)
568 : {
569 : int retval;
570 0 : char *p;
571 :
572 0 : p = buf + size - 1;
573 0 : if (size < 1)
574 0 : p = buf;
575 0 : retval = kprintf(fmt, TOBUFONLY | TOCOUNT, &p, buf, ap);
576 0 : if (size > 0)
577 0 : *(p) = 0; /* null terminate */
578 0 : return(retval);
579 0 : }
580 :
581 : /*
582 : * kprintf: scaled down version of printf(3).
583 : *
584 : * this version based on vfprintf() from libc which was derived from
585 : * software contributed to Berkeley by Chris Torek.
586 : *
587 : * The additional format %b is supported to decode error registers.
588 : * Its usage is:
589 : *
590 : * printf("reg=%b\n", regval, "<base><arg>*");
591 : *
592 : * where <base> is the output base expressed as a control character, e.g.
593 : * \10 gives octal; \20 gives hex. Each arg is a sequence of characters,
594 : * the first of which gives the bit number to be inspected (origin 1), and
595 : * the next characters (up to a control character, i.e. a character <= 32),
596 : * give the name of the register. Thus:
597 : *
598 : * kprintf("reg=%b\n", 3, "\10\2BITTWO\1BITONE\n");
599 : *
600 : * would produce output:
601 : *
602 : * reg=3<BITTWO,BITONE>
603 : *
604 : * To support larger integers (> 32 bits), %b formatting will also accept
605 : * control characters in the region 0x80 - 0xff. 0x80 refers to bit 0,
606 : * 0x81 refers to bit 1, and so on. The equivalent string to the above is:
607 : *
608 : * kprintf("reg=%b\n", 3, "\10\201BITTWO\200BITONE\n");
609 : *
610 : * and would produce the same output.
611 : *
612 : * Like the rest of printf, %b can be prefixed to handle various size
613 : * modifiers, eg. %b is for "int", %lb is for "long", and %llb supports
614 : * "long long".
615 : *
616 : * This code is large and complicated...
617 : */
618 :
619 : /*
620 : * macros for converting digits to letters and vice versa
621 : */
622 : #define to_digit(c) ((c) - '0')
623 : #define is_digit(c) ((unsigned)to_digit(c) <= 9)
624 : #define to_char(n) ((n) + '0')
625 :
626 : /*
627 : * flags used during conversion.
628 : */
629 : #define ALT 0x001 /* alternate form */
630 : #define HEXPREFIX 0x002 /* add 0x or 0X prefix */
631 : #define LADJUST 0x004 /* left adjustment */
632 : #define LONGDBL 0x008 /* long double; unimplemented */
633 : #define LONGINT 0x010 /* long integer */
634 : #define QUADINT 0x020 /* quad integer */
635 : #define SHORTINT 0x040 /* short integer */
636 : #define ZEROPAD 0x080 /* zero (as opposed to blank) pad */
637 : #define FPT 0x100 /* Floating point number */
638 : #define SIZEINT 0x200 /* (signed) size_t */
639 :
640 : /*
641 : * To extend shorts properly, we need both signed and unsigned
642 : * argument extraction methods.
643 : */
644 : #define SARG() \
645 : (flags&QUADINT ? va_arg(ap, quad_t) : \
646 : flags&LONGINT ? va_arg(ap, long) : \
647 : flags&SIZEINT ? va_arg(ap, ssize_t) : \
648 : flags&SHORTINT ? (long)(short)va_arg(ap, int) : \
649 : (long)va_arg(ap, int))
650 : #define UARG() \
651 : (flags&QUADINT ? va_arg(ap, u_quad_t) : \
652 : flags&LONGINT ? va_arg(ap, u_long) : \
653 : flags&SIZEINT ? va_arg(ap, size_t) : \
654 : flags&SHORTINT ? (u_long)(u_short)va_arg(ap, int) : \
655 : (u_long)va_arg(ap, u_int))
656 :
657 : #define KPRINTF_PUTCHAR(C) do { \
658 : int chr = (C); \
659 : ret += 1; \
660 : if (oflags & TOBUFONLY) { \
661 : if ((vp != NULL) && (sbuf == tailp)) { \
662 : if (!(oflags & TOCOUNT)) \
663 : goto overflow; \
664 : } else \
665 : *sbuf++ = chr; \
666 : } else { \
667 : kputchar(chr, oflags, (struct tty *)vp); \
668 : } \
669 : } while(0)
670 :
671 : int
672 0 : kprintf(const char *fmt0, int oflags, void *vp, char *sbuf, va_list ap)
673 : {
674 : char *fmt; /* format string */
675 : int ch; /* character from fmt */
676 : int n; /* handy integer (short term usage) */
677 : char *cp = NULL; /* handy char pointer (short term usage) */
678 : int flags; /* flags as above */
679 : int ret; /* return value accumulator */
680 : int width; /* width from format (%8d), or 0 */
681 : int prec; /* precision from format (%.3d), or -1 */
682 : char sign; /* sign prefix (' ', '+', '-', or \0) */
683 :
684 : u_quad_t _uquad; /* integer arguments %[diouxX] */
685 : enum { OCT, DEC, HEX } base;/* base for [diouxX] conversion */
686 : int dprec; /* a copy of prec if [diouxX], 0 otherwise */
687 : int realsz; /* field size expanded by dprec */
688 : int size = 0; /* size of converted field or string */
689 : char *xdigs = NULL; /* digits for [xX] conversion */
690 0 : char buf[KPRINTF_BUFSIZE]; /* space for %c, %[diouxX] */
691 : char *tailp = NULL; /* tail pointer for snprintf */
692 :
693 0 : if (oflags & TOCONS)
694 0 : MUTEX_ASSERT_LOCKED(&kprintf_mutex);
695 :
696 0 : if ((oflags & TOBUFONLY) && (vp != NULL))
697 0 : tailp = *(char **)vp;
698 :
699 : fmt = (char *)fmt0;
700 : ret = 0;
701 :
702 : /*
703 : * Scan the format for conversions (`%' character).
704 : */
705 0 : for (;;) {
706 0 : while (*fmt != '%' && *fmt) {
707 0 : KPRINTF_PUTCHAR(*fmt++);
708 : }
709 0 : if (*fmt == 0)
710 : goto done;
711 :
712 0 : fmt++; /* skip over '%' */
713 :
714 : flags = 0;
715 : dprec = 0;
716 : width = 0;
717 : prec = -1;
718 0 : sign = '\0';
719 :
720 0 : rflag: ch = *fmt++;
721 0 : reswitch: switch (ch) {
722 : /* XXX: non-standard '%b' format */
723 : case 'b': {
724 : char *b, *z;
725 : int tmp;
726 0 : _uquad = UARG();
727 0 : b = va_arg(ap, char *);
728 0 : if (*b == 8)
729 0 : snprintf(buf, sizeof buf, "%llo", _uquad);
730 0 : else if (*b == 10)
731 0 : snprintf(buf, sizeof buf, "%lld", _uquad);
732 0 : else if (*b == 16)
733 0 : snprintf(buf, sizeof buf, "%llx", _uquad);
734 : else
735 0 : break;
736 0 : b++;
737 :
738 0 : z = buf;
739 0 : while (*z) {
740 0 : KPRINTF_PUTCHAR(*z++);
741 : }
742 :
743 0 : if (_uquad) {
744 : tmp = 0;
745 0 : while ((n = *b++) != 0) {
746 0 : if (n & 0x80)
747 0 : n &= 0x7f;
748 0 : else if (n <= ' ')
749 0 : n = n - 1;
750 0 : if (_uquad & (1LL << n)) {
751 0 : KPRINTF_PUTCHAR(tmp ? ',':'<');
752 0 : while (*b > ' ' &&
753 0 : (*b & 0x80) == 0) {
754 0 : KPRINTF_PUTCHAR(*b);
755 0 : b++;
756 : }
757 : tmp = 1;
758 0 : } else {
759 0 : while (*b > ' ' &&
760 0 : (*b & 0x80) == 0)
761 0 : b++;
762 : }
763 : }
764 0 : if (tmp) {
765 0 : KPRINTF_PUTCHAR('>');
766 : }
767 : }
768 0 : continue; /* no output */
769 : }
770 :
771 : case ' ':
772 : /*
773 : * ``If the space and + flags both appear, the space
774 : * flag will be ignored.''
775 : * -- ANSI X3J11
776 : */
777 0 : if (!sign)
778 0 : sign = ' ';
779 0 : goto rflag;
780 : case '#':
781 0 : flags |= ALT;
782 0 : goto rflag;
783 : case '*':
784 : /*
785 : * ``A negative field width argument is taken as a
786 : * - flag followed by a positive field width.''
787 : * -- ANSI X3J11
788 : * They don't exclude field widths read from args.
789 : */
790 0 : if ((width = va_arg(ap, int)) >= 0)
791 0 : goto rflag;
792 0 : width = -width;
793 : /* FALLTHROUGH */
794 : case '-':
795 0 : flags |= LADJUST;
796 0 : goto rflag;
797 : case '+':
798 : sign = '+';
799 0 : goto rflag;
800 : case '.':
801 0 : if ((ch = *fmt++) == '*') {
802 0 : n = va_arg(ap, int);
803 0 : prec = n < 0 ? -1 : n;
804 0 : goto rflag;
805 : }
806 : n = 0;
807 0 : while (is_digit(ch)) {
808 0 : n = 10 * n + to_digit(ch);
809 0 : ch = *fmt++;
810 : }
811 0 : prec = n < 0 ? -1 : n;
812 0 : goto reswitch;
813 : case '0':
814 : /*
815 : * ``Note that 0 is taken as a flag, not as the
816 : * beginning of a field width.''
817 : * -- ANSI X3J11
818 : */
819 0 : flags |= ZEROPAD;
820 0 : goto rflag;
821 : case '1': case '2': case '3': case '4':
822 : case '5': case '6': case '7': case '8': case '9':
823 : n = 0;
824 0 : do {
825 0 : n = 10 * n + to_digit(ch);
826 0 : ch = *fmt++;
827 0 : } while (is_digit(ch));
828 : width = n;
829 0 : goto reswitch;
830 : case 'h':
831 0 : flags |= SHORTINT;
832 0 : goto rflag;
833 : case 'l':
834 0 : if (*fmt == 'l') {
835 0 : fmt++;
836 0 : flags |= QUADINT;
837 0 : } else {
838 0 : flags |= LONGINT;
839 : }
840 0 : goto rflag;
841 : case 'q':
842 0 : flags |= QUADINT;
843 0 : goto rflag;
844 : case 'z':
845 0 : flags |= SIZEINT;
846 0 : goto rflag;
847 : case 'c':
848 0 : *(cp = buf) = va_arg(ap, int);
849 : size = 1;
850 : sign = '\0';
851 0 : break;
852 : case 't':
853 : /* ptrdiff_t */
854 : /* FALLTHROUGH */
855 : case 'D':
856 0 : flags |= LONGINT;
857 : /*FALLTHROUGH*/
858 : case 'd':
859 : case 'i':
860 0 : _uquad = SARG();
861 0 : if ((quad_t)_uquad < 0) {
862 0 : _uquad = -_uquad;
863 : sign = '-';
864 0 : }
865 : base = DEC;
866 0 : goto number;
867 : case 'n':
868 : /* %n is unsupported in the kernel; just skip it */
869 0 : if (flags & QUADINT)
870 0 : (void)va_arg(ap, quad_t *);
871 0 : else if (flags & LONGINT)
872 0 : (void)va_arg(ap, long *);
873 0 : else if (flags & SHORTINT)
874 0 : (void)va_arg(ap, short *);
875 0 : else if (flags & SIZEINT)
876 0 : (void)va_arg(ap, ssize_t *);
877 : else
878 0 : (void)va_arg(ap, int *);
879 0 : continue; /* no output */
880 : case 'O':
881 0 : flags |= LONGINT;
882 : /*FALLTHROUGH*/
883 : case 'o':
884 0 : _uquad = UARG();
885 : base = OCT;
886 0 : goto nosign;
887 : case 'p':
888 : /*
889 : * ``The argument shall be a pointer to void. The
890 : * value of the pointer is converted to a sequence
891 : * of printable characters, in an implementation-
892 : * defined manner.''
893 : * -- ANSI X3J11
894 : */
895 0 : _uquad = (u_long)va_arg(ap, void *);
896 : base = HEX;
897 : xdigs = "0123456789abcdef";
898 0 : flags |= HEXPREFIX;
899 : ch = 'x';
900 0 : goto nosign;
901 : case 's':
902 0 : if ((cp = va_arg(ap, char *)) == NULL)
903 : cp = "(null)";
904 0 : if (prec >= 0) {
905 : /*
906 : * can't use strlen; can only look for the
907 : * NUL in the first `prec' characters, and
908 : * strlen() will go further.
909 : */
910 0 : char *p = memchr(cp, 0, prec);
911 :
912 0 : if (p != NULL) {
913 0 : size = p - cp;
914 0 : if (size > prec)
915 0 : size = prec;
916 : } else
917 : size = prec;
918 0 : } else
919 0 : size = strlen(cp);
920 : sign = '\0';
921 0 : break;
922 : case 'U':
923 0 : flags |= LONGINT;
924 : /*FALLTHROUGH*/
925 : case 'u':
926 0 : _uquad = UARG();
927 : base = DEC;
928 0 : goto nosign;
929 : case 'X':
930 : xdigs = "0123456789ABCDEF";
931 0 : goto hex;
932 : case 'x':
933 0 : xdigs = "0123456789abcdef";
934 0 : hex: _uquad = UARG();
935 : base = HEX;
936 : /* leading 0x/X only if non-zero */
937 0 : if (flags & ALT && _uquad != 0)
938 0 : flags |= HEXPREFIX;
939 :
940 : /* unsigned conversions */
941 0 : nosign: sign = '\0';
942 : /*
943 : * ``... diouXx conversions ... if a precision is
944 : * specified, the 0 flag will be ignored.''
945 : * -- ANSI X3J11
946 : */
947 0 : number: if ((dprec = prec) >= 0)
948 0 : flags &= ~ZEROPAD;
949 :
950 : /*
951 : * ``The result of converting a zero value with an
952 : * explicit precision of zero is no characters.''
953 : * -- ANSI X3J11
954 : */
955 0 : cp = buf + KPRINTF_BUFSIZE;
956 0 : if (_uquad != 0 || prec != 0) {
957 : /*
958 : * Unsigned mod is hard, and unsigned mod
959 : * by a constant is easier than that by
960 : * a variable; hence this switch.
961 : */
962 0 : switch (base) {
963 : case OCT:
964 0 : do {
965 0 : *--cp = to_char(_uquad & 7);
966 0 : _uquad >>= 3;
967 0 : } while (_uquad);
968 : /* handle octal leading 0 */
969 0 : if (flags & ALT && *cp != '0')
970 0 : *--cp = '0';
971 : break;
972 :
973 : case DEC:
974 : /* many numbers are 1 digit */
975 0 : while (_uquad >= 10) {
976 0 : *--cp = to_char(_uquad % 10);
977 0 : _uquad /= 10;
978 : }
979 0 : *--cp = to_char(_uquad);
980 0 : break;
981 :
982 : case HEX:
983 0 : do {
984 0 : *--cp = xdigs[_uquad & 15];
985 0 : _uquad >>= 4;
986 0 : } while (_uquad);
987 : break;
988 :
989 : default:
990 : cp = "bug in kprintf: bad base";
991 0 : size = strlen(cp);
992 0 : goto skipsize;
993 : }
994 : }
995 0 : size = buf + KPRINTF_BUFSIZE - cp;
996 : skipsize:
997 : break;
998 : default: /* "%?" prints ?, unless ? is NUL */
999 0 : if (ch == '\0')
1000 : goto done;
1001 : /* pretend it was %c with argument ch */
1002 0 : cp = buf;
1003 0 : *cp = ch;
1004 : size = 1;
1005 : sign = '\0';
1006 0 : break;
1007 : }
1008 :
1009 : /*
1010 : * All reasonable formats wind up here. At this point, `cp'
1011 : * points to a string which (if not flags&LADJUST) should be
1012 : * padded out to `width' places. If flags&ZEROPAD, it should
1013 : * first be prefixed by any sign or other prefix; otherwise,
1014 : * it should be blank padded before the prefix is emitted.
1015 : * After any left-hand padding and prefixing, emit zeroes
1016 : * required by a decimal [diouxX] precision, then print the
1017 : * string proper, then emit zeroes required by any leftover
1018 : * floating precision; finally, if LADJUST, pad with blanks.
1019 : *
1020 : * Compute actual size, so we know how much to pad.
1021 : * size excludes decimal prec; realsz includes it.
1022 : */
1023 0 : realsz = dprec > size ? dprec : size;
1024 0 : if (sign)
1025 0 : realsz++;
1026 0 : else if (flags & HEXPREFIX)
1027 0 : realsz+= 2;
1028 :
1029 : /* right-adjusting blank padding */
1030 0 : if ((flags & (LADJUST|ZEROPAD)) == 0) {
1031 0 : n = width - realsz;
1032 0 : while (n-- > 0)
1033 0 : KPRINTF_PUTCHAR(' ');
1034 : }
1035 :
1036 : /* prefix */
1037 0 : if (sign) {
1038 0 : KPRINTF_PUTCHAR(sign);
1039 0 : } else if (flags & HEXPREFIX) {
1040 0 : KPRINTF_PUTCHAR('0');
1041 0 : KPRINTF_PUTCHAR(ch);
1042 : }
1043 :
1044 : /* right-adjusting zero padding */
1045 0 : if ((flags & (LADJUST|ZEROPAD)) == ZEROPAD) {
1046 0 : n = width - realsz;
1047 0 : while (n-- > 0)
1048 0 : KPRINTF_PUTCHAR('0');
1049 : }
1050 :
1051 : /* leading zeroes from decimal precision */
1052 0 : n = dprec - size;
1053 0 : while (n-- > 0)
1054 0 : KPRINTF_PUTCHAR('0');
1055 :
1056 : /* the string or number proper */
1057 0 : while (size--)
1058 0 : KPRINTF_PUTCHAR(*cp++);
1059 : /* left-adjusting padding (always blank) */
1060 0 : if (flags & LADJUST) {
1061 0 : n = width - realsz;
1062 0 : while (n-- > 0)
1063 0 : KPRINTF_PUTCHAR(' ');
1064 : }
1065 : }
1066 :
1067 : done:
1068 0 : if ((oflags & TOBUFONLY) && (vp != NULL))
1069 0 : *(char **)vp = sbuf;
1070 : overflow:
1071 0 : return (ret);
1072 : /* NOTREACHED */
1073 0 : }
1074 :
1075 : #if __GNUC_PREREQ__(2,96)
1076 : /*
1077 : * XXX - these functions shouldn't be in the kernel, but gcc 3.X feels like
1078 : * translating some printf calls to puts and since it doesn't seem
1079 : * possible to just turn off parts of those optimizations (some of
1080 : * them are really useful), we have to provide a dummy puts and putchar
1081 : * that are wrappers around printf.
1082 : */
1083 : int puts(const char *);
1084 : int putchar(int c);
1085 :
1086 : int
1087 0 : puts(const char *str)
1088 : {
1089 0 : printf("%s\n", str);
1090 :
1091 0 : return (0);
1092 : }
1093 :
1094 : int
1095 0 : putchar(int c)
1096 : {
1097 0 : printf("%c", c);
1098 :
1099 0 : return (c);
1100 : }
1101 :
1102 :
1103 : #endif
|