root/kern/subr_prf.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. __assert
  2. tablefull
  3. panic
  4. splassert_fail
  5. log
  6. logpri
  7. addlog
  8. kputchar
  9. uprintf
  10. tprintf_open
  11. tprintf_close
  12. tprintf
  13. ttyprintf
  14. db_printf
  15. printf
  16. vprintf
  17. snprintf
  18. vsnprintf
  19. kprintf
  20. puts
  21. putchar

    1 /*      $OpenBSD: subr_prf.c,v 1.70 2007/04/26 20:28:25 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. 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/buf.h>
   43 #include <sys/conf.h>
   44 #include <sys/reboot.h>
   45 #include <sys/msgbuf.h>
   46 #include <sys/proc.h>
   47 #include <sys/ioctl.h>
   48 #include <sys/vnode.h>
   49 #include <sys/file.h>
   50 #include <sys/tty.h>
   51 #include <sys/tprintf.h>
   52 #include <sys/syslog.h>
   53 #include <sys/malloc.h>
   54 #include <sys/pool.h>
   55 #include <sys/mutex.h>
   56 
   57 #include <dev/cons.h>
   58 
   59 /*
   60  * note that stdarg.h and the ansi style va_start macro is used for both
   61  * ansi and traditional c compilers.
   62  */
   63 #include <sys/stdarg.h>
   64 
   65 #ifdef KGDB
   66 #include <sys/kgdb.h>
   67 #include <machine/cpu.h>
   68 #endif
   69 #ifdef DDB
   70 #include <ddb/db_output.h>      /* db_printf, db_putchar prototypes */
   71 #include <ddb/db_var.h>         /* db_log, db_radix */
   72 #endif
   73 #if defined(UVM_SWAP_ENCRYPT)
   74 extern int uvm_doswapencrypt;
   75 #endif
   76 
   77 
   78 /*
   79  * defines
   80  */
   81 
   82 /* flags for kprintf */
   83 #define TOCONS          0x01    /* to the console */
   84 #define TOTTY           0x02    /* to the process' tty */
   85 #define TOLOG           0x04    /* to the kernel message buffer */
   86 #define TOBUFONLY       0x08    /* to the buffer (only) [for snprintf] */
   87 #define TODDB           0x10    /* to ddb console */
   88 #define TOCOUNT         0x20    /* act like [v]snprintf */
   89 
   90 /* max size buffer kprintf needs to print quad_t [size in base 8 + \0] */
   91 #define KPRINTF_BUFSIZE         (sizeof(quad_t) * NBBY / 3 + 2)
   92 
   93 
   94 /*
   95  * local prototypes
   96  */
   97 
   98 int      kprintf(const char *, int, void *, char *, va_list);
   99 void     kputchar(int, int, struct tty *);
  100 
  101 struct mutex kprintf_mutex = MUTEX_INITIALIZER(IPL_HIGH);
  102 
  103 /*
  104  * globals
  105  */
  106 
  107 extern 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  * panic on spl assertion failure?
  134  */
  135 int splassert_ctl = 1;
  136 
  137 /*
  138  * v_putc: routine to putc on virtual console
  139  *
  140  * the v_putc pointer can be used to redirect the console cnputc elsewhere
  141  * [e.g. to a "virtual console"].
  142  */
  143 
  144 void (*v_putc)(int) = cnputc;   /* start with cnputc (normal cons) */
  145 
  146 
  147 /*
  148  * functions
  149  */
  150 
  151 /*
  152  *      Partial support (the failure case) of the assertion facility
  153  *      commonly found in userland.
  154  */
  155 void
  156 __assert(const char *t, const char *f, int l, const char *e)
  157 {
  158 
  159         panic("kernel %sassertion \"%s\" failed: file \"%s\", line %d",
  160                 t, e, f, l);
  161 }
  162 
  163 /*
  164  * tablefull: warn that a system table is full
  165  */
  166 
  167 void
  168 tablefull(const char *tab)
  169 {
  170         log(LOG_ERR, "%s: table is full\n", tab);
  171 }
  172 
  173 /*
  174  * panic: handle an unresolvable fatal error
  175  *
  176  * prints "panic: <message>" and reboots.   if called twice (i.e. recursive
  177  * call) we avoid trying to sync the disk and just reboot (to avoid
  178  * recursive panics).
  179  */
  180 
  181 void
  182 panic(const char *fmt, ...)
  183 {
  184         static char panicbuf[512];
  185         int bootopt;
  186         va_list ap;
  187 
  188         bootopt = RB_AUTOBOOT | RB_DUMP;
  189 #if defined(UVM_SWAP_ENCRYPT)
  190         if (uvm_doswapencrypt)
  191                 bootopt &= ~RB_DUMP;
  192 #endif
  193         va_start(ap, fmt);
  194         if (panicstr)
  195                 bootopt |= RB_NOSYNC;
  196         else {
  197                 vsnprintf(panicbuf, sizeof panicbuf, fmt, ap);
  198                 panicstr = panicbuf;
  199         }
  200         va_end(ap);
  201 
  202         printf("panic: ");
  203         va_start(ap, fmt);
  204         vprintf(fmt, ap);
  205         printf("\n");
  206         va_end(ap);
  207 
  208 #ifdef KGDB
  209         kgdb_panic();
  210 #endif
  211 #ifdef KADB
  212         if (boothowto & RB_KDB)
  213                 kdbpanic();
  214 #endif
  215 #ifdef DDB
  216         if (db_panic)
  217                 Debugger();
  218         else
  219                 db_stack_dump();
  220 #endif
  221         boot(bootopt);
  222 }
  223 
  224 /*
  225  * We print only the function name. The file name is usually very long and
  226  * would eat tons of space in the kernel.
  227  */
  228 void
  229 splassert_fail(int wantipl, int haveipl, const char *func)
  230 {
  231 
  232         printf("splassert: %s: want %d have %d\n", func, wantipl, haveipl);
  233         switch (splassert_ctl) {
  234         case 1:
  235                 break;
  236         case 2:
  237 #ifdef DDB
  238                 db_stack_dump();
  239 #endif
  240                 break;
  241         case 3:
  242 #ifdef DDB
  243                 db_stack_dump();
  244                 Debugger();
  245 #endif
  246                 break;
  247         default:
  248                 panic("spl assertion failure in %s", func);
  249         }
  250 }
  251 
  252 /*
  253  * kernel logging functions: log, logpri, addlog
  254  */
  255 
  256 /*
  257  * log: write to the log buffer
  258  *
  259  * => will not sleep [so safe to call from interrupt]
  260  * => will log to console if /dev/klog isn't open
  261  */
  262 
  263 void
  264 log(int level, const char *fmt, ...)
  265 {
  266         int s;
  267         va_list ap;
  268 
  269         s = splhigh();
  270         logpri(level);          /* log the level first */
  271         va_start(ap, fmt);
  272         kprintf(fmt, TOLOG, NULL, NULL, ap);
  273         va_end(ap);
  274         splx(s);
  275         if (!log_open) {
  276                 va_start(ap, fmt);
  277                 kprintf(fmt, TOCONS, NULL, NULL, ap);
  278                 va_end(ap);
  279         }
  280         logwakeup();            /* wake up anyone waiting for log msgs */
  281 }
  282 
  283 /*
  284  * logpri: log the priority level to the klog
  285  */
  286 
  287 void
  288 logpri(int level)
  289 {
  290         char *p;
  291         char snbuf[KPRINTF_BUFSIZE];
  292 
  293         kputchar('<', TOLOG, NULL);
  294         snprintf(snbuf, sizeof snbuf, "%d", level);
  295         for (p = snbuf ; *p ; p++)
  296                 kputchar(*p, TOLOG, NULL);
  297         kputchar('>', TOLOG, NULL);
  298 }
  299 
  300 /*
  301  * addlog: add info to previous log message
  302  */
  303 
  304 int
  305 addlog(const char *fmt, ...)
  306 {
  307         int s;
  308         va_list ap;
  309 
  310         s = splhigh();
  311         va_start(ap, fmt);
  312         kprintf(fmt, TOLOG, NULL, NULL, ap);
  313         va_end(ap);
  314         splx(s);
  315         if (!log_open) {
  316                 va_start(ap, fmt);
  317                 kprintf(fmt, TOCONS, NULL, NULL, ap);
  318                 va_end(ap);
  319         }
  320         logwakeup();
  321         return(0);
  322 }
  323 
  324 
  325 /*
  326  * kputchar: print a single character on console or user terminal.
  327  *
  328  * => if console, then the last MSGBUFS chars are saved in msgbuf
  329  *      for inspection later (e.g. dmesg/syslog)
  330  */
  331 void
  332 kputchar(int c, int flags, struct tty *tp)
  333 {
  334         extern int msgbufmapped;
  335 
  336         if (panicstr)
  337                 constty = NULL;
  338         if ((flags & TOCONS) && tp == NULL && constty) {
  339                 tp = constty;
  340                 flags |= TOTTY;
  341         }
  342         if ((flags & TOTTY) && tp && tputchar(c, tp) < 0 &&
  343             (flags & TOCONS) && tp == constty)
  344                 constty = NULL;
  345         if ((flags & TOLOG) &&
  346             c != '\0' && c != '\r' && c != 0177 && msgbufmapped)
  347                 msgbuf_putchar(c);
  348         if ((flags & TOCONS) && constty == NULL && c != '\0')
  349                 (*v_putc)(c);
  350 #ifdef DDB
  351         if (flags & TODDB)
  352                 db_putchar(c);
  353 #endif
  354 }
  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 uprintf(const char *fmt, ...)
  367 {
  368         struct proc *p = curproc;
  369         va_list ap;
  370 
  371         if (p->p_flag & P_CONTROLT && p->p_session->s_ttyvp) {
  372                 va_start(ap, fmt);
  373                 kprintf(fmt, TOTTY, p->p_session->s_ttyp, NULL, ap);
  374                 va_end(ap);
  375         }
  376 }
  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  *
  392  * => returns NULL if process can't be printed to
  393  */
  394 
  395 tpr_t
  396 tprintf_open(struct proc *p)
  397 {
  398 
  399         if (p->p_flag & P_CONTROLT && p->p_session->s_ttyvp) {
  400                 SESSHOLD(p->p_session);
  401                 return ((tpr_t) p->p_session);
  402         }
  403         return ((tpr_t) NULL);
  404 }
  405 
  406 /*
  407  * tprintf_close: dispose of a tprintf handle obtained with tprintf_open
  408  */
  409 
  410 void
  411 tprintf_close(tpr_t sess)
  412 {
  413 
  414         if (sess)
  415                 SESSRELE((struct session *) sess);
  416 }
  417 
  418 /*
  419  * tprintf: given tprintf handle to a process [obtained with tprintf_open],
  420  * send a message to the controlling tty for that process.
  421  *
  422  * => also sends message to /dev/klog
  423  */
  424 void
  425 tprintf(tpr_t tpr, const char *fmt, ...)
  426 {
  427         struct session *sess = (struct session *)tpr;
  428         struct tty *tp = NULL;
  429         int flags = TOLOG;
  430         va_list ap;
  431 
  432         logpri(LOG_INFO);
  433         if (sess && sess->s_ttyvp && ttycheckoutq(sess->s_ttyp, 0)) {
  434                 flags |= TOTTY;
  435                 tp = sess->s_ttyp;
  436         }
  437         va_start(ap, fmt);
  438         kprintf(fmt, flags, tp, NULL, ap);
  439         va_end(ap);
  440         logwakeup();
  441 }
  442 
  443 #endif  /* NFSSERVER || NFSCLIENT */
  444 
  445 
  446 /*
  447  * ttyprintf: send a message to a specific tty
  448  *
  449  * => should be used only by tty driver or anything that knows the
  450  *      underlying tty will not be revoked(2)'d away.  [otherwise,
  451  *      use tprintf]
  452  */
  453 void
  454 ttyprintf(struct tty *tp, const char *fmt, ...)
  455 {
  456         va_list ap;
  457 
  458         va_start(ap, fmt);
  459         kprintf(fmt, TOTTY, tp, NULL, ap);
  460         va_end(ap);
  461 }
  462 
  463 #ifdef DDB
  464 
  465 /*
  466  * db_printf: printf for DDB (via db_putchar)
  467  */
  468 
  469 int
  470 db_printf(const char *fmt, ...)
  471 {
  472         va_list ap;
  473         int flags, retval;
  474 
  475         flags = TODDB;
  476         if (db_log)
  477                 flags |= TOLOG;
  478         va_start(ap, fmt);
  479         retval = kprintf(fmt, flags, NULL, NULL, ap);
  480         va_end(ap);
  481         return(retval);
  482 }
  483 
  484 #endif /* DDB */
  485 
  486 
  487 /*
  488  * normal kernel printf functions: printf, vprintf, snprintf
  489  */
  490 
  491 /*
  492  * printf: print a message to the console and the log
  493  */
  494 int
  495 printf(const char *fmt, ...)
  496 {
  497         va_list ap;
  498         int savintr, retval;
  499 
  500         mtx_enter(&kprintf_mutex);
  501 
  502         savintr = consintr;             /* disable interrupts */
  503         consintr = 0;
  504         va_start(ap, fmt);
  505         retval = kprintf(fmt, TOCONS | TOLOG, NULL, NULL, ap);
  506         va_end(ap);
  507         if (!panicstr)
  508                 logwakeup();
  509         consintr = savintr;             /* reenable interrupts */
  510 
  511         mtx_leave(&kprintf_mutex);
  512 
  513         return(retval);
  514 }
  515 
  516 /*
  517  * vprintf: print a message to the console and the log [already have a
  518  *      va_list]
  519  */
  520 
  521 int
  522 vprintf(const char *fmt, va_list ap)
  523 {
  524         int savintr, retval;
  525 
  526         mtx_enter(&kprintf_mutex);
  527 
  528         savintr = consintr;             /* disable interrupts */
  529         consintr = 0;
  530         retval = kprintf(fmt, TOCONS | TOLOG, NULL, NULL, ap);
  531         if (!panicstr)
  532                 logwakeup();
  533         consintr = savintr;             /* reenable interrupts */
  534 
  535         mtx_leave(&kprintf_mutex);
  536 
  537         return (retval);
  538 }
  539 
  540 /*
  541  * snprintf: print a message to a buffer
  542  */
  543 int
  544 snprintf(char *buf, size_t size, const char *fmt, ...)
  545 {
  546         int retval;
  547         va_list ap;
  548         char *p;
  549 
  550         p = buf + size - 1;
  551         if (size < 1)
  552                 p = buf;
  553         va_start(ap, fmt);
  554         retval = kprintf(fmt, TOBUFONLY | TOCOUNT, &p, buf, ap);
  555         va_end(ap);
  556         if (size > 0)
  557                 *(p) = 0;       /* null terminate */
  558         return(retval);
  559 }
  560 
  561 /*
  562  * vsnprintf: print a message to a buffer [already have va_alist]
  563  */
  564 int
  565 vsnprintf(char *buf, size_t size, const char *fmt, va_list ap)
  566 {
  567         int retval;
  568         char *p;
  569 
  570         p = buf + size - 1;
  571         if (size < 1)
  572                 p = buf;
  573         retval = kprintf(fmt, TOBUFONLY | TOCOUNT, &p, buf, ap);
  574         if (size > 0)
  575                 *(p) = 0;       /* null terminate */
  576         return(retval);
  577 }
  578 
  579 /*
  580  * kprintf: scaled down version of printf(3).
  581  *
  582  * this version based on vfprintf() from libc which was derived from
  583  * software contributed to Berkeley by Chris Torek.
  584  *
  585  * Two additional formats:
  586  *
  587  * The 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 
  639         /*
  640          * To extend shorts properly, we need both signed and unsigned
  641          * argument extraction methods.
  642          */
  643 #define SARG() \
  644         (flags&QUADINT ? va_arg(ap, quad_t) : \
  645             flags&LONGINT ? va_arg(ap, long) : \
  646             flags&SHORTINT ? (long)(short)va_arg(ap, int) : \
  647             (long)va_arg(ap, int))
  648 #define UARG() \
  649         (flags&QUADINT ? va_arg(ap, u_quad_t) : \
  650             flags&LONGINT ? va_arg(ap, u_long) : \
  651             flags&SHORTINT ? (u_long)(u_short)va_arg(ap, int) : \
  652             (u_long)va_arg(ap, u_int))
  653 
  654 #define KPRINTF_PUTCHAR(C) do {                                 \
  655         int chr = (C);                                                  \
  656         ret += 1;                                                       \
  657         if (oflags & TOBUFONLY) {                                       \
  658                 if ((vp != NULL) && (sbuf == tailp)) {                  \
  659                         if (!(oflags & TOCOUNT))                                \
  660                                 goto overflow;                          \
  661                 } else                                                  \
  662                         *sbuf++ = chr;                                  \
  663         } else {                                                        \
  664                 kputchar(chr, oflags, (struct tty *)vp);                        \
  665         }                                                               \
  666 } while(0)
  667 
  668 int
  669 kprintf(const char *fmt0, int oflags, void *vp, char *sbuf, va_list ap)
  670 {
  671         char *fmt;              /* format string */
  672         int ch;                 /* character from fmt */
  673         int n;                  /* handy integer (short term usage) */
  674         char *cp = NULL;        /* handy char pointer (short term usage) */
  675         int flags;              /* flags as above */
  676         int ret;                /* return value accumulator */
  677         int width;              /* width from format (%8d), or 0 */
  678         int prec;               /* precision from format (%.3d), or -1 */
  679         char sign;              /* sign prefix (' ', '+', '-', or \0) */
  680 
  681         u_quad_t _uquad;        /* integer arguments %[diouxX] */
  682         enum { OCT, DEC, HEX } base;/* base for [diouxX] conversion */
  683         int dprec;              /* a copy of prec if [diouxX], 0 otherwise */
  684         int realsz;             /* field size expanded by dprec */
  685         int size = 0;           /* size of converted field or string */
  686         char *xdigs = NULL;     /* digits for [xX] conversion */
  687         char buf[KPRINTF_BUFSIZE]; /* space for %c, %[diouxX] */
  688         char *tailp = NULL;     /* tail pointer for snprintf */
  689 
  690         if ((oflags & TOBUFONLY) && (vp != NULL))
  691                 tailp = *(char **)vp;
  692 
  693         fmt = (char *)fmt0;
  694         ret = 0;
  695 
  696         /*
  697          * Scan the format for conversions (`%' character).
  698          */
  699         for (;;) {
  700                 while (*fmt != '%' && *fmt) {
  701                         KPRINTF_PUTCHAR(*fmt++);
  702                 }
  703                 if (*fmt == 0)
  704                         goto done;
  705 
  706                 fmt++;          /* skip over '%' */
  707 
  708                 flags = 0;
  709                 dprec = 0;
  710                 width = 0;
  711                 prec = -1;
  712                 sign = '\0';
  713 
  714 rflag:          ch = *fmt++;
  715 reswitch:       switch (ch) {
  716                 /* XXX: non-standard '%b' format */
  717                 case 'b': {
  718                         char *b, *z;
  719                         int tmp;
  720                         _uquad = UARG();
  721                         b = va_arg(ap, char *);
  722                         if (*b == 8)
  723                                 snprintf(buf, sizeof buf, "%llo", _uquad);
  724                         else if (*b == 10)
  725                                 snprintf(buf, sizeof buf, "%lld", _uquad);
  726                         else if (*b == 16)
  727                                 snprintf(buf, sizeof buf, "%llx", _uquad);
  728                         else
  729                                 break;
  730                         b++;
  731 
  732                         z = buf;
  733                         while (*z) {
  734                                 KPRINTF_PUTCHAR(*z++);
  735                         }
  736 
  737                         if (_uquad) {
  738                                 tmp = 0;
  739                                 while ((n = *b++) != 0) {
  740                                         if (n & 0x80)
  741                                                 n &= 0x7f;
  742                                         else if (n <= ' ')
  743                                                 n = n - 1;
  744                                         if (_uquad & (1LL << n)) {
  745                                                 KPRINTF_PUTCHAR(tmp ? ',':'<');
  746                                                 while (*b > ' ' &&
  747                                                     (*b & 0x80) == 0) {
  748                                                         KPRINTF_PUTCHAR(*b);
  749                                                         b++;
  750                                                 }
  751                                                 tmp = 1;
  752                                         } else {
  753                                                 while (*b > ' ' &&
  754                                                     (*b & 0x80) == 0)
  755                                                         b++;
  756                                         }
  757                                 }
  758                                 if (tmp) {
  759                                         KPRINTF_PUTCHAR('>');
  760                                 }
  761                         }
  762                         continue;       /* no output */
  763                 }
  764 
  765 #ifdef DDB
  766                 /* XXX: non-standard '%r' format (print int in db_radix) */
  767                 case 'r':
  768                         if ((oflags & TODDB) == 0)
  769                                 goto default_case;
  770 
  771                         if (db_radix == 16)
  772                                 goto case_z;    /* signed hex */
  773                         _uquad = SARG();
  774                         if ((quad_t)_uquad < 0) {
  775                                 _uquad = -_uquad;
  776                                 sign = '-';
  777                         }
  778                         base = (db_radix == 8) ? OCT : DEC;
  779                         goto number;
  780 
  781 
  782                 /* XXX: non-standard '%z' format ("signed hex", a "hex %i")*/
  783                 case 'z':
  784                 case_z:
  785                         if ((oflags & TODDB) == 0)
  786                                 goto default_case;
  787 
  788                         xdigs = "0123456789abcdef";
  789                         ch = 'x';       /* the 'x' in '0x' (below) */
  790                         _uquad = SARG();
  791                         base = HEX;
  792                         /* leading 0x/X only if non-zero */
  793                         if (flags & ALT && _uquad != 0)
  794                                 flags |= HEXPREFIX;
  795                         if ((quad_t)_uquad < 0) {
  796                                 _uquad = -_uquad;
  797                                 sign = '-';
  798                         }
  799                         goto number;
  800 #endif
  801 
  802                 case ' ':
  803                         /*
  804                          * ``If the space and + flags both appear, the space
  805                          * flag will be ignored.''
  806                          *      -- ANSI X3J11
  807                          */
  808                         if (!sign)
  809                                 sign = ' ';
  810                         goto rflag;
  811                 case '#':
  812                         flags |= ALT;
  813                         goto rflag;
  814                 case '*':
  815                         /*
  816                          * ``A negative field width argument is taken as a
  817                          * - flag followed by a positive field width.''
  818                          *      -- ANSI X3J11
  819                          * They don't exclude field widths read from args.
  820                          */
  821                         if ((width = va_arg(ap, int)) >= 0)
  822                                 goto rflag;
  823                         width = -width;
  824                         /* FALLTHROUGH */
  825                 case '-':
  826                         flags |= LADJUST;
  827                         goto rflag;
  828                 case '+':
  829                         sign = '+';
  830                         goto rflag;
  831                 case '.':
  832                         if ((ch = *fmt++) == '*') {
  833                                 n = va_arg(ap, int);
  834                                 prec = n < 0 ? -1 : n;
  835                                 goto rflag;
  836                         }
  837                         n = 0;
  838                         while (is_digit(ch)) {
  839                                 n = 10 * n + to_digit(ch);
  840                                 ch = *fmt++;
  841                         }
  842                         prec = n < 0 ? -1 : n;
  843                         goto reswitch;
  844                 case '0':
  845                         /*
  846                          * ``Note that 0 is taken as a flag, not as the
  847                          * beginning of a field width.''
  848                          *      -- ANSI X3J11
  849                          */
  850                         flags |= ZEROPAD;
  851                         goto rflag;
  852                 case '1': case '2': case '3': case '4':
  853                 case '5': case '6': case '7': case '8': case '9':
  854                         n = 0;
  855                         do {
  856                                 n = 10 * n + to_digit(ch);
  857                                 ch = *fmt++;
  858                         } while (is_digit(ch));
  859                         width = n;
  860                         goto reswitch;
  861                 case 'h':
  862                         flags |= SHORTINT;
  863                         goto rflag;
  864                 case 'l':
  865                         if (*fmt == 'l') {
  866                                 fmt++;
  867                                 flags |= QUADINT;
  868                         } else {
  869                                 flags |= LONGINT;
  870                         }
  871                         goto rflag;
  872                 case 'q':
  873                         flags |= QUADINT;
  874                         goto rflag;
  875                 case 'c':
  876                         *(cp = buf) = va_arg(ap, int);
  877                         size = 1;
  878                         sign = '\0';
  879                         break;
  880                 case 'D':
  881                         flags |= LONGINT;
  882                         /*FALLTHROUGH*/
  883                 case 'd':
  884                 case 'i':
  885                         _uquad = SARG();
  886                         if ((quad_t)_uquad < 0) {
  887                                 _uquad = -_uquad;
  888                                 sign = '-';
  889                         }
  890                         base = DEC;
  891                         goto number;
  892                 case 'n':
  893 #ifdef DDB
  894                 /* XXX: non-standard '%n' format */
  895                 /*
  896                  * XXX: HACK!   DDB wants '%n' to be a '%u' printed
  897                  * in db_radix format.   this should die since '%n'
  898                  * is already defined in standard printf to write
  899                  * the number of chars printed so far to the arg (which
  900                  * should be a pointer.
  901                  */
  902                         if (oflags & TODDB) {
  903                                 if (db_radix == 16)
  904                                         ch = 'x';       /* convert to %x */
  905                                 else if (db_radix == 8)
  906                                         ch = 'o';       /* convert to %o */
  907                                 else
  908                                         ch = 'u';       /* convert to %u */
  909 
  910                                 /* ... and start again */
  911                                 goto reswitch;
  912                         }
  913 
  914 #endif
  915                         if (flags & QUADINT)
  916                                 *va_arg(ap, quad_t *) = ret;
  917                         else if (flags & LONGINT)
  918                                 *va_arg(ap, long *) = ret;
  919                         else if (flags & SHORTINT)
  920                                 *va_arg(ap, short *) = ret;
  921                         else
  922                                 *va_arg(ap, int *) = ret;
  923                         continue;       /* no output */
  924                 case 'O':
  925                         flags |= LONGINT;
  926                         /*FALLTHROUGH*/
  927                 case 'o':
  928                         _uquad = UARG();
  929                         base = OCT;
  930                         goto nosign;
  931                 case 'p':
  932                         /*
  933                          * ``The argument shall be a pointer to void.  The
  934                          * value of the pointer is converted to a sequence
  935                          * of printable characters, in an implementation-
  936                          * defined manner.''
  937                          *      -- ANSI X3J11
  938                          */
  939                         /* NOSTRICT */
  940                         _uquad = (u_long)va_arg(ap, void *);
  941                         base = HEX;
  942                         xdigs = "0123456789abcdef";
  943                         flags |= HEXPREFIX;
  944                         ch = 'x';
  945                         goto nosign;
  946                 case 's':
  947                         if ((cp = va_arg(ap, char *)) == NULL)
  948                                 cp = "(null)";
  949                         if (prec >= 0) {
  950                                 /*
  951                                  * can't use strlen; can only look for the
  952                                  * NUL in the first `prec' characters, and
  953                                  * strlen() will go further.
  954                                  */
  955                                 char *p = memchr(cp, 0, prec);
  956 
  957                                 if (p != NULL) {
  958                                         size = p - cp;
  959                                         if (size > prec)
  960                                                 size = prec;
  961                                 } else
  962                                         size = prec;
  963                         } else
  964                                 size = strlen(cp);
  965                         sign = '\0';
  966                         break;
  967                 case 'U':
  968                         flags |= LONGINT;
  969                         /*FALLTHROUGH*/
  970                 case 'u':
  971                         _uquad = UARG();
  972                         base = DEC;
  973                         goto nosign;
  974                 case 'X':
  975                         xdigs = "0123456789ABCDEF";
  976                         goto hex;
  977                 case 'x':
  978                         xdigs = "0123456789abcdef";
  979 hex:                    _uquad = UARG();
  980                         base = HEX;
  981                         /* leading 0x/X only if non-zero */
  982                         if (flags & ALT && _uquad != 0)
  983                                 flags |= HEXPREFIX;
  984 
  985                         /* unsigned conversions */
  986 nosign:                 sign = '\0';
  987                         /*
  988                          * ``... diouXx conversions ... if a precision is
  989                          * specified, the 0 flag will be ignored.''
  990                          *      -- ANSI X3J11
  991                          */
  992 number:                 if ((dprec = prec) >= 0)
  993                                 flags &= ~ZEROPAD;
  994 
  995                         /*
  996                          * ``The result of converting a zero value with an
  997                          * explicit precision of zero is no characters.''
  998                          *      -- ANSI X3J11
  999                          */
 1000                         cp = buf + KPRINTF_BUFSIZE;
 1001                         if (_uquad != 0 || prec != 0) {
 1002                                 /*
 1003                                  * Unsigned mod is hard, and unsigned mod
 1004                                  * by a constant is easier than that by
 1005                                  * a variable; hence this switch.
 1006                                  */
 1007                                 switch (base) {
 1008                                 case OCT:
 1009                                         do {
 1010                                                 *--cp = to_char(_uquad & 7);
 1011                                                 _uquad >>= 3;
 1012                                         } while (_uquad);
 1013                                         /* handle octal leading 0 */
 1014                                         if (flags & ALT && *cp != '0')
 1015                                                 *--cp = '0';
 1016                                         break;
 1017 
 1018                                 case DEC:
 1019                                         /* many numbers are 1 digit */
 1020                                         while (_uquad >= 10) {
 1021                                                 *--cp = to_char(_uquad % 10);
 1022                                                 _uquad /= 10;
 1023                                         }
 1024                                         *--cp = to_char(_uquad);
 1025                                         break;
 1026 
 1027                                 case HEX:
 1028                                         do {
 1029                                                 *--cp = xdigs[_uquad & 15];
 1030                                                 _uquad >>= 4;
 1031                                         } while (_uquad);
 1032                                         break;
 1033 
 1034                                 default:
 1035                                         cp = "bug in kprintf: bad base";
 1036                                         size = strlen(cp);
 1037                                         goto skipsize;
 1038                                 }
 1039                         }
 1040                         size = buf + KPRINTF_BUFSIZE - cp;
 1041                 skipsize:
 1042                         break;
 1043                 default:        /* "%?" prints ?, unless ? is NUL */
 1044 #ifdef DDB
 1045                 default_case:   /* DDB */
 1046 #endif
 1047                         if (ch == '\0')
 1048                                 goto done;
 1049                         /* pretend it was %c with argument ch */
 1050                         cp = buf;
 1051                         *cp = ch;
 1052                         size = 1;
 1053                         sign = '\0';
 1054                         break;
 1055                 }
 1056 
 1057                 /*
 1058                  * All reasonable formats wind up here.  At this point, `cp'
 1059                  * points to a string which (if not flags&LADJUST) should be
 1060                  * padded out to `width' places.  If flags&ZEROPAD, it should
 1061                  * first be prefixed by any sign or other prefix; otherwise,
 1062                  * it should be blank padded before the prefix is emitted.
 1063                  * After any left-hand padding and prefixing, emit zeroes
 1064                  * required by a decimal [diouxX] precision, then print the
 1065                  * string proper, then emit zeroes required by any leftover
 1066                  * floating precision; finally, if LADJUST, pad with blanks.
 1067                  *
 1068                  * Compute actual size, so we know how much to pad.
 1069                  * size excludes decimal prec; realsz includes it.
 1070                  */
 1071                 realsz = dprec > size ? dprec : size;
 1072                 if (sign)
 1073                         realsz++;
 1074                 else if (flags & HEXPREFIX)
 1075                         realsz+= 2;
 1076 
 1077                 /* right-adjusting blank padding */
 1078                 if ((flags & (LADJUST|ZEROPAD)) == 0) {
 1079                         n = width - realsz;
 1080                         while (n-- > 0)
 1081                                 KPRINTF_PUTCHAR(' ');
 1082                 }
 1083 
 1084                 /* prefix */
 1085                 if (sign) {
 1086                         KPRINTF_PUTCHAR(sign);
 1087                 } else if (flags & HEXPREFIX) {
 1088                         KPRINTF_PUTCHAR('0');
 1089                         KPRINTF_PUTCHAR(ch);
 1090                 }
 1091 
 1092                 /* right-adjusting zero padding */
 1093                 if ((flags & (LADJUST|ZEROPAD)) == ZEROPAD) {
 1094                         n = width - realsz;
 1095                         while (n-- > 0)
 1096                                 KPRINTF_PUTCHAR('0');
 1097                 }
 1098 
 1099                 /* leading zeroes from decimal precision */
 1100                 n = dprec - size;
 1101                 while (n-- > 0)
 1102                         KPRINTF_PUTCHAR('0');
 1103 
 1104                 /* the string or number proper */
 1105                 while (size--)
 1106                         KPRINTF_PUTCHAR(*cp++);
 1107                 /* left-adjusting padding (always blank) */
 1108                 if (flags & LADJUST) {
 1109                         n = width - realsz;
 1110                         while (n-- > 0)
 1111                                 KPRINTF_PUTCHAR(' ');
 1112                 }
 1113         }
 1114 
 1115 done:
 1116         if ((oflags & TOBUFONLY) && (vp != NULL))
 1117                 *(char **)vp = sbuf;
 1118 overflow:
 1119         return (ret);
 1120         /* NOTREACHED */
 1121 }
 1122 
 1123 #if __GNUC_PREREQ__(2,96)
 1124 /*
 1125  * XXX - these functions shouldn't be in the kernel, but gcc 3.X feels like
 1126  *       translating some printf calls to puts and since it doesn't seem
 1127  *       possible to just turn off parts of those optimizations (some of
 1128  *       them are really useful), we have to provide a dummy puts and putchar
 1129  *       that are wrappers around printf.
 1130  */
 1131 int     puts(const char *);
 1132 int     putchar(int c);
 1133 
 1134 int
 1135 puts(const char *str)
 1136 {
 1137         printf("%s\n", str);
 1138 
 1139         return (0);
 1140 }
 1141 
 1142 int
 1143 putchar(int c)
 1144 {
 1145         printf("%c", c);
 1146 
 1147         return (c);
 1148 }
 1149 
 1150 
 1151 #endif

/* [<][>][^][v][top][bottom][index][help] */