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