The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/kern/subr_prf.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*      $NetBSD: subr_prf.c,v 1.124.4.1 2009/02/02 19:47:47 snj Exp $   */
    2 
    3 /*-
    4  * Copyright (c) 1986, 1988, 1991, 1993
    5  *      The Regents of the University of California.  All rights reserved.
    6  * (c) UNIX System Laboratories, Inc.
    7  * All or some portions of this file are derived from material licensed
    8  * to the University of California by American Telephone and Telegraph
    9  * Co. or Unix System Laboratories, Inc. and are reproduced herein with
   10  * the permission of UNIX System Laboratories, Inc.
   11  *
   12  * Redistribution and use in source and binary forms, with or without
   13  * modification, are permitted provided that the following conditions
   14  * are met:
   15  * 1. Redistributions of source code must retain the above copyright
   16  *    notice, this list of conditions and the following disclaimer.
   17  * 2. Redistributions in binary form must reproduce the above copyright
   18  *    notice, this list of conditions and the following disclaimer in the
   19  *    documentation and/or other materials provided with the distribution.
   20  * 3. Neither the name of the University nor the names of its contributors
   21  *    may be used to endorse or promote products derived from this software
   22  *    without specific prior written permission.
   23  *
   24  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   25  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   26  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   27  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   28  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   29  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   30  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   31  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   33  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   34  * SUCH DAMAGE.
   35  *
   36  *      @(#)subr_prf.c  8.4 (Berkeley) 5/4/95
   37  */
   38 
   39 #include <sys/cdefs.h>
   40 __KERNEL_RCSID(0, "$NetBSD: subr_prf.c,v 1.124.4.1 2009/02/02 19:47:47 snj Exp $");
   41 
   42 #include "opt_ddb.h"
   43 #include "opt_ipkdb.h"
   44 #include "opt_kgdb.h"
   45 #include "opt_dump.h"
   46 
   47 #include <sys/param.h>
   48 #include <sys/stdint.h>
   49 #include <sys/systm.h>
   50 #include <sys/buf.h>
   51 #include <sys/device.h>
   52 #include <sys/reboot.h>
   53 #include <sys/msgbuf.h>
   54 #include <sys/proc.h>
   55 #include <sys/ioctl.h>
   56 #include <sys/vnode.h>
   57 #include <sys/file.h>
   58 #include <sys/tty.h>
   59 #include <sys/tprintf.h>
   60 #include <sys/syslog.h>
   61 #include <sys/malloc.h>
   62 #include <sys/kprintf.h>
   63 #include <sys/atomic.h>
   64 #include <sys/cpu.h>
   65 
   66 #include <dev/cons.h>
   67 
   68 #include <net/if.h>
   69 
   70 #ifdef DDB
   71 #include <ddb/ddbvar.h>
   72 #include <machine/db_machdep.h>
   73 #include <ddb/db_command.h>
   74 #include <ddb/db_interface.h>
   75 #endif
   76 
   77 #ifdef IPKDB
   78 #include <ipkdb/ipkdb.h>
   79 #endif
   80 
   81 struct simplelock kprintf_slock = SIMPLELOCK_INITIALIZER;
   82 
   83 /*
   84  * note that stdarg.h and the ansi style va_start macro is used for both
   85  * ansi and traditional c complers.
   86  * XXX: this requires that stdarg.h define: va_alist and va_dcl
   87  */
   88 #include <machine/stdarg.h>
   89 
   90 
   91 #ifdef KGDB
   92 #include <sys/kgdb.h>
   93 #endif
   94 #ifdef DDB
   95 #include <ddb/db_output.h>      /* db_printf, db_putchar prototypes */
   96 #endif
   97 
   98 
   99 /*
  100  * defines
  101  */
  102 
  103 
  104 /*
  105  * local prototypes
  106  */
  107 
  108 static void      putchar(int, int, struct tty *);
  109 
  110 
  111 /*
  112  * globals
  113  */
  114 
  115 extern  struct tty *constty;    /* pointer to console "window" tty */
  116 extern  int log_open;   /* subr_log: is /dev/klog open? */
  117 const   char *panicstr; /* arg to first call to panic (used as a flag
  118                            to indicate that panic has already been called). */
  119 struct cpu_info *paniccpu;      /* cpu that first paniced */
  120 long    panicstart, panicend;   /* position in the msgbuf of the start and
  121                                    end of the formatted panicstr. */
  122 int     doing_shutdown; /* set to indicate shutdown in progress */
  123 
  124 #ifndef DUMP_ON_PANIC
  125 #define DUMP_ON_PANIC   1
  126 #endif
  127 int     dumponpanic = DUMP_ON_PANIC;
  128 
  129 /*
  130  * v_putc: routine to putc on virtual console
  131  *
  132  * the v_putc pointer can be used to redirect the console cnputc elsewhere
  133  * [e.g. to a "virtual console"].
  134  */
  135 
  136 void (*v_putc)(int) = cnputc;   /* start with cnputc (normal cons) */
  137 void (*v_flush)(void) = cnflush;        /* start with cnflush (normal cons) */
  138 
  139 
  140 /*
  141  * functions
  142  */
  143 
  144 /*
  145  * twiddle: spin a little propellor on the console.
  146  */
  147 
  148 void
  149 twiddle(void)
  150 {
  151         static const char twiddle_chars[] = "|/-\\";
  152         static int pos;
  153         int s;
  154 
  155         KPRINTF_MUTEX_ENTER(s);
  156 
  157         putchar(twiddle_chars[pos++ & 3], TOCONS, NULL);
  158         putchar('\b', TOCONS, NULL);
  159 
  160         KPRINTF_MUTEX_EXIT(s);
  161 }
  162 
  163 /*
  164  * panic: handle an unresolvable fatal error
  165  *
  166  * prints "panic: <message>" and reboots.   if called twice (i.e. recursive
  167  * call) we avoid trying to sync the disk and just reboot (to avoid
  168  * recursive panics).
  169  */
  170 
  171 void
  172 panic(const char *fmt, ...)
  173 {
  174         CPU_INFO_ITERATOR cii;
  175         struct cpu_info *ci, *oci;
  176         int bootopt;
  177         va_list ap;
  178 
  179         /*
  180          * Disable preemption.  If already panicing on another CPU, sit
  181          * here and spin until the system is rebooted.  Allow the CPU that
  182          * first paniced to panic again.
  183          */
  184         kpreempt_disable();
  185         ci = curcpu();
  186         oci = atomic_cas_ptr((void *)&paniccpu, NULL, ci);
  187         if (oci != NULL && oci != ci) {
  188                 /* Give interrupts a chance to try and prevent deadlock. */
  189                 for (;;) {
  190                         DELAY(10);
  191                 }
  192         }
  193 
  194         /*
  195          * Convert the current thread to a bound thread and prevent all
  196          * CPUs from scheduling unbound jobs.  Do so without taking any
  197          * locks.
  198          */
  199         curlwp->l_pflag |= LP_BOUND;
  200         for (CPU_INFO_FOREACH(cii, ci)) {
  201                 ci->ci_schedstate.spc_flags |= SPCF_OFFLINE;
  202         }
  203 
  204         bootopt = RB_AUTOBOOT | RB_NOSYNC;
  205         if (dumponpanic)
  206                 bootopt |= RB_DUMP;
  207         if (!panicstr)
  208                 panicstr = fmt;
  209         doing_shutdown = 1;
  210 
  211         if (msgbufenabled && msgbufp->msg_magic == MSG_MAGIC)
  212                 panicstart = msgbufp->msg_bufx;
  213 
  214         va_start(ap, fmt);
  215         printf("panic: ");
  216         vprintf(fmt, ap);
  217         printf("\n");
  218         va_end(ap);
  219 
  220         if (msgbufenabled && msgbufp->msg_magic == MSG_MAGIC)
  221                 panicend = msgbufp->msg_bufx;
  222 
  223 #ifdef IPKDB
  224         ipkdb_panic();
  225 #endif
  226 #ifdef KGDB
  227         kgdb_panic();
  228 #endif
  229 #ifdef KADB
  230         if (boothowto & RB_KDB)
  231                 kdbpanic();
  232 #endif
  233 #ifdef DDB
  234         if (db_onpanic == 1)
  235                 Debugger();
  236         else if (db_onpanic >= 0) {
  237                 static int intrace = 0;
  238 
  239                 if (intrace == 0) {
  240                         intrace = 1;
  241                         printf("Begin traceback...\n");
  242                         db_stack_trace_print(
  243                             (db_expr_t)(intptr_t)__builtin_frame_address(0),
  244                             true, 65535, "", printf);
  245                         printf("End traceback...\n");
  246                         intrace = 0;
  247                 } else
  248                         printf("Faulted in mid-traceback; aborting...");
  249                 if (db_onpanic == 2)
  250                         Debugger();
  251         }
  252 #endif
  253         cpu_reboot(bootopt, NULL);
  254 }
  255 
  256 /*
  257  * kernel logging functions: log, logpri, addlog
  258  */
  259 
  260 /*
  261  * log: write to the log buffer
  262  *
  263  * => will not sleep [so safe to call from interrupt]
  264  * => will log to console if /dev/klog isn't open
  265  */
  266 
  267 void
  268 log(int level, const char *fmt, ...)
  269 {
  270         int s;
  271         va_list ap;
  272 
  273         KPRINTF_MUTEX_ENTER(s);
  274 
  275         klogpri(level);         /* log the level first */
  276         va_start(ap, fmt);
  277         kprintf(fmt, TOLOG, NULL, NULL, ap);
  278         va_end(ap);
  279         if (!log_open) {
  280                 va_start(ap, fmt);
  281                 kprintf(fmt, TOCONS, NULL, NULL, ap);
  282                 va_end(ap);
  283         }
  284 
  285         KPRINTF_MUTEX_EXIT(s);
  286 
  287         logwakeup();            /* wake up anyone waiting for log msgs */
  288 }
  289 
  290 /*
  291  * vlog: write to the log buffer [already have va_alist]
  292  */
  293 
  294 void
  295 vlog(int level, const char *fmt, va_list ap)
  296 {
  297         int s;
  298 
  299         KPRINTF_MUTEX_ENTER(s);
  300 
  301         klogpri(level);         /* log the level first */
  302         kprintf(fmt, TOLOG, NULL, NULL, ap);
  303         if (!log_open)
  304                 kprintf(fmt, TOCONS, NULL, NULL, ap);
  305 
  306         KPRINTF_MUTEX_EXIT(s);
  307 
  308         logwakeup();            /* wake up anyone waiting for log msgs */
  309 }
  310 
  311 /*
  312  * logpri: log the priority level to the klog
  313  */
  314 
  315 void
  316 logpri(int level)
  317 {
  318         int s;
  319 
  320         KPRINTF_MUTEX_ENTER(s);
  321         klogpri(level);
  322         KPRINTF_MUTEX_EXIT(s);
  323 }
  324 
  325 /*
  326  * Note: we must be in the mutex here!
  327  */
  328 void
  329 klogpri(int level)
  330 {
  331         char *p;
  332         char snbuf[KPRINTF_BUFSIZE];
  333 
  334         putchar('<', TOLOG, NULL);
  335         snprintf(snbuf, sizeof(snbuf), "%d", level);
  336         for (p = snbuf ; *p ; p++)
  337                 putchar(*p, TOLOG, NULL);
  338         putchar('>', TOLOG, NULL);
  339 }
  340 
  341 /*
  342  * addlog: add info to previous log message
  343  */
  344 
  345 void
  346 addlog(const char *fmt, ...)
  347 {
  348         int s;
  349         va_list ap;
  350 
  351         KPRINTF_MUTEX_ENTER(s);
  352 
  353         va_start(ap, fmt);
  354         kprintf(fmt, TOLOG, NULL, NULL, ap);
  355         va_end(ap);
  356         if (!log_open) {
  357                 va_start(ap, fmt);
  358                 kprintf(fmt, TOCONS, NULL, NULL, ap);
  359                 va_end(ap);
  360         }
  361 
  362         KPRINTF_MUTEX_EXIT(s);
  363 
  364         logwakeup();
  365 }
  366 
  367 
  368 /*
  369  * putchar: print a single character on console or user terminal.
  370  *
  371  * => if console, then the last MSGBUFS chars are saved in msgbuf
  372  *      for inspection later (e.g. dmesg/syslog)
  373  * => we must already be in the mutex!
  374  */
  375 static void
  376 putchar(int c, int flags, struct tty *tp)
  377 {
  378 
  379         if (panicstr)
  380                 constty = NULL;
  381         if ((flags & TOCONS) && tp == NULL && constty) {
  382                 tp = constty;
  383                 flags |= TOTTY;
  384         }
  385         if ((flags & TOTTY) && tp &&
  386             tputchar(c, flags, tp) < 0 &&
  387             (flags & TOCONS) && tp == constty)
  388                 constty = NULL;
  389         if ((flags & TOLOG) &&
  390             c != '\0' && c != '\r' && c != 0177)
  391                 logputchar(c);
  392         if ((flags & TOCONS) && constty == NULL && c != '\0')
  393                 (*v_putc)(c);
  394 #ifdef DDB
  395         if (flags & TODDB)
  396                 db_putchar(c);
  397 #endif
  398 }
  399 
  400 
  401 /*
  402  * uprintf: print to the controlling tty of the current process
  403  *
  404  * => we may block if the tty queue is full
  405  * => no message is printed if the queue doesn't clear in a reasonable
  406  *      time
  407  */
  408 
  409 void
  410 uprintf(const char *fmt, ...)
  411 {
  412         struct proc *p = curproc;
  413         va_list ap;
  414 
  415         /* mutex_enter(proc_lock); XXXSMP */
  416 
  417         if (p->p_lflag & PL_CONTROLT && p->p_session->s_ttyvp) {
  418                 /* No mutex needed; going to process TTY. */
  419                 va_start(ap, fmt);
  420                 kprintf(fmt, TOTTY, p->p_session->s_ttyp, NULL, ap);
  421                 va_end(ap);
  422         }
  423 
  424         /* mutex_exit(proc_lock); XXXSMP */
  425 }
  426 
  427 void
  428 uprintf_locked(const char *fmt, ...)
  429 {
  430         struct proc *p = curproc;
  431         va_list ap;
  432 
  433         if (p->p_lflag & PL_CONTROLT && p->p_session->s_ttyvp) {
  434                 /* No mutex needed; going to process TTY. */
  435                 va_start(ap, fmt);
  436                 kprintf(fmt, TOTTY, p->p_session->s_ttyp, NULL, ap);
  437                 va_end(ap);
  438         }
  439 }
  440 
  441 /*
  442  * tprintf functions: used to send messages to a specific process
  443  *
  444  * usage:
  445  *   get a tpr_t handle on a process "p" by using "tprintf_open(p)"
  446  *   use the handle when calling "tprintf"
  447  *   when done, do a "tprintf_close" to drop the handle
  448  */
  449 
  450 /*
  451  * tprintf_open: get a tprintf handle on a process "p"
  452  *
  453  * => returns NULL if process can't be printed to
  454  */
  455 
  456 tpr_t
  457 tprintf_open(struct proc *p)
  458 {
  459         tpr_t cookie;
  460 
  461         cookie = NULL;
  462 
  463         mutex_enter(proc_lock);
  464         if (p->p_lflag & PL_CONTROLT && p->p_session->s_ttyvp) {
  465                 SESSHOLD(p->p_session);
  466                 cookie = (tpr_t)p->p_session;
  467         }
  468         mutex_exit(proc_lock);
  469 
  470         return cookie;
  471 }
  472 
  473 /*
  474  * tprintf_close: dispose of a tprintf handle obtained with tprintf_open
  475  */
  476 
  477 void
  478 tprintf_close(tpr_t sess)
  479 {
  480 
  481         if (sess) {
  482                 mutex_enter(proc_lock);
  483                 SESSRELE((struct session *) sess);
  484                 mutex_exit(proc_lock);
  485         }
  486 }
  487 
  488 /*
  489  * tprintf: given tprintf handle to a process [obtained with tprintf_open],
  490  * send a message to the controlling tty for that process.
  491  *
  492  * => also sends message to /dev/klog
  493  */
  494 void
  495 tprintf(tpr_t tpr, const char *fmt, ...)
  496 {
  497         struct session *sess = (struct session *)tpr;
  498         struct tty *tp = NULL;
  499         int s, flags = TOLOG;
  500         va_list ap;
  501 
  502         /* mutex_enter(proc_lock); XXXSMP */
  503         if (sess && sess->s_ttyvp && ttycheckoutq(sess->s_ttyp, 0)) {
  504                 flags |= TOTTY;
  505                 tp = sess->s_ttyp;
  506         }
  507 
  508         KPRINTF_MUTEX_ENTER(s);
  509 
  510         klogpri(LOG_INFO);
  511         va_start(ap, fmt);
  512         kprintf(fmt, flags, tp, NULL, ap);
  513         va_end(ap);
  514 
  515         KPRINTF_MUTEX_EXIT(s);
  516         /* mutex_exit(proc_lock);       XXXSMP */
  517 
  518         logwakeup();
  519 }
  520 
  521 
  522 /*
  523  * ttyprintf: send a message to a specific tty
  524  *
  525  * => should be used only by tty driver or anything that knows the
  526  *    underlying tty will not be revoked(2)'d away.  [otherwise,
  527  *    use tprintf]
  528  */
  529 void
  530 ttyprintf(struct tty *tp, const char *fmt, ...)
  531 {
  532         va_list ap;
  533 
  534         /* No mutex needed; going to process TTY. */
  535         va_start(ap, fmt);
  536         kprintf(fmt, TOTTY, tp, NULL, ap);
  537         va_end(ap);
  538 }
  539 
  540 #ifdef DDB
  541 
  542 /*
  543  * db_printf: printf for DDB (via db_putchar)
  544  */
  545 
  546 void
  547 db_printf(const char *fmt, ...)
  548 {
  549         va_list ap;
  550 
  551         /* No mutex needed; DDB pauses all processors. */
  552         va_start(ap, fmt);
  553         kprintf(fmt, TODDB, NULL, NULL, ap);
  554         va_end(ap);
  555 
  556         if (db_tee_msgbuf) {
  557                 va_start(ap, fmt);
  558                 kprintf(fmt, TOLOG, NULL, NULL, ap);
  559                 va_end(ap);
  560         };
  561 }
  562 
  563 void
  564 db_vprintf(const char *fmt, va_list ap)
  565 {
  566 
  567         /* No mutex needed; DDB pauses all processors. */
  568         kprintf(fmt, TODDB, NULL, NULL, ap);
  569         if (db_tee_msgbuf)
  570                 kprintf(fmt, TOLOG, NULL, NULL, ap);
  571 }
  572 
  573 #endif /* DDB */
  574 
  575 static void
  576 kprintf_internal(const char *fmt, int oflags, void *vp, char *sbuf, ...)
  577 {
  578         va_list ap;
  579         
  580         va_start(ap, sbuf);
  581         (void)kprintf(fmt, oflags, vp, sbuf, ap);
  582         va_end(ap);
  583 }
  584 
  585 /*
  586  * Device autoconfiguration printf routines.  These change their
  587  * behavior based on the AB_* flags in boothowto.  If AB_SILENT
  588  * is set, messages never go to the console (but they still always
  589  * go to the log).  AB_VERBOSE overrides AB_SILENT.
  590  */
  591 
  592 /*
  593  * aprint_normal: Send to console unless AB_QUIET.  Always goes
  594  * to the log.
  595  */
  596 static void
  597 aprint_normal_internal(const char *prefix, const char *fmt, va_list ap)
  598 {
  599         int s, flags = TOLOG;
  600 
  601         if ((boothowto & (AB_SILENT|AB_QUIET)) == 0 ||
  602             (boothowto & AB_VERBOSE) != 0)
  603                 flags |= TOCONS;
  604 
  605         KPRINTF_MUTEX_ENTER(s);
  606 
  607         if (prefix)
  608                 kprintf_internal("%s: ", flags, NULL, NULL, prefix);
  609         kprintf(fmt, flags, NULL, NULL, ap);
  610 
  611         KPRINTF_MUTEX_EXIT(s);
  612 
  613         if (!panicstr)
  614                 logwakeup();
  615 }
  616 
  617 void
  618 aprint_normal(const char *fmt, ...)
  619 {
  620         va_list ap;
  621 
  622         va_start(ap, fmt);
  623         aprint_normal_internal(NULL, fmt, ap);
  624         va_end(ap);
  625 }
  626 
  627 void
  628 aprint_normal_dev(device_t dv, const char *fmt, ...)
  629 {
  630         va_list ap;
  631 
  632         va_start(ap, fmt);
  633         aprint_normal_internal(device_xname(dv), fmt, ap);
  634         va_end(ap);
  635 }
  636 
  637 void
  638 aprint_normal_ifnet(struct ifnet *ifp, const char *fmt, ...)
  639 {
  640         va_list ap;
  641 
  642         va_start(ap, fmt);
  643         aprint_normal_internal(ifp->if_xname, fmt, ap);
  644         va_end(ap);
  645 }
  646 
  647 /*
  648  * aprint_error: Send to console unless AB_QUIET.  Always goes
  649  * to the log.  Also counts the number of times called so other
  650  * parts of the kernel can report the number of errors during a
  651  * given phase of system startup.
  652  */
  653 static int aprint_error_count;
  654 
  655 int
  656 aprint_get_error_count(void)
  657 {
  658         int count, s;
  659 
  660         KPRINTF_MUTEX_ENTER(s);
  661 
  662         count = aprint_error_count;
  663         aprint_error_count = 0;
  664 
  665         KPRINTF_MUTEX_EXIT(s);
  666 
  667         return (count);
  668 }
  669 
  670 static void
  671 aprint_error_internal(const char *prefix, const char *fmt, va_list ap)
  672 {
  673         int s, flags = TOLOG;
  674 
  675         if ((boothowto & (AB_SILENT|AB_QUIET)) == 0 ||
  676             (boothowto & AB_VERBOSE) != 0)
  677                 flags |= TOCONS;
  678 
  679         KPRINTF_MUTEX_ENTER(s);
  680 
  681         aprint_error_count++;
  682 
  683         if (prefix)
  684                 kprintf_internal("%s: ", flags, NULL, NULL, prefix);
  685         kprintf(fmt, flags, NULL, NULL, ap);
  686 
  687         KPRINTF_MUTEX_EXIT(s);
  688 
  689         if (!panicstr)
  690                 logwakeup();
  691 }
  692 
  693 void
  694 aprint_error(const char *fmt, ...)
  695 {
  696         va_list ap;
  697 
  698         va_start(ap, fmt);
  699         aprint_error_internal(NULL, fmt, ap);
  700         va_end(ap);
  701 }
  702 
  703 void
  704 aprint_error_dev(device_t dv, const char *fmt, ...)
  705 {
  706         va_list ap;
  707 
  708         va_start(ap, fmt);
  709         aprint_error_internal(device_xname(dv), fmt, ap);
  710         va_end(ap);
  711 }
  712 
  713 void
  714 aprint_error_ifnet(struct ifnet *ifp, const char *fmt, ...)
  715 {
  716         va_list ap;
  717 
  718         va_start(ap, fmt);
  719         aprint_error_internal(ifp->if_xname, fmt, ap);
  720         va_end(ap);
  721 }
  722 
  723 /*
  724  * aprint_naive: Send to console only if AB_QUIET.  Never goes
  725  * to the log.
  726  */
  727 static void
  728 aprint_naive_internal(const char *prefix, const char *fmt, va_list ap)
  729 {
  730         int s;
  731 
  732         if ((boothowto & (AB_QUIET|AB_SILENT|AB_VERBOSE)) != AB_QUIET)
  733                 return;
  734 
  735         KPRINTF_MUTEX_ENTER(s);
  736 
  737         if (prefix)
  738                 kprintf_internal("%s: ", TOCONS, NULL, NULL, prefix);
  739         kprintf(fmt, TOCONS, NULL, NULL, ap);
  740 
  741         KPRINTF_MUTEX_EXIT(s);
  742 }
  743 
  744 void
  745 aprint_naive(const char *fmt, ...)
  746 {
  747         va_list ap;
  748 
  749         va_start(ap, fmt);
  750         aprint_naive_internal(NULL, fmt, ap);
  751         va_end(ap);
  752 }
  753 
  754 void
  755 aprint_naive_dev(device_t dv, const char *fmt, ...)
  756 {
  757         va_list ap;
  758 
  759         va_start(ap, fmt);
  760         aprint_naive_internal(device_xname(dv), fmt, ap);
  761         va_end(ap);
  762 }
  763 
  764 void
  765 aprint_naive_ifnet(struct ifnet *ifp, const char *fmt, ...)
  766 {
  767         va_list ap;
  768 
  769         va_start(ap, fmt);
  770         aprint_naive_internal(ifp->if_xname, fmt, ap);
  771         va_end(ap);
  772 }
  773 
  774 /*
  775  * aprint_verbose: Send to console only if AB_VERBOSE.  Always
  776  * goes to the log.
  777  */
  778 static void
  779 aprint_verbose_internal(const char *prefix, const char *fmt, va_list ap)
  780 {
  781         int s, flags = TOLOG;
  782 
  783         if (boothowto & AB_VERBOSE)
  784                 flags |= TOCONS;
  785 
  786         KPRINTF_MUTEX_ENTER(s);
  787 
  788         if (prefix)
  789                 kprintf_internal("%s: ", flags, NULL, NULL, prefix);
  790         kprintf(fmt, flags, NULL, NULL, ap);
  791 
  792         KPRINTF_MUTEX_EXIT(s);
  793 
  794         if (!panicstr)
  795                 logwakeup();
  796 }
  797 
  798 void
  799 aprint_verbose(const char *fmt, ...)
  800 {
  801         va_list ap;
  802 
  803         va_start(ap, fmt);
  804         aprint_verbose_internal(NULL, fmt, ap);
  805         va_end(ap);
  806 }
  807 
  808 void
  809 aprint_verbose_dev(device_t dv, const char *fmt, ...)
  810 {
  811         va_list ap;
  812 
  813         va_start(ap, fmt);
  814         aprint_verbose_internal(device_xname(dv), fmt, ap);
  815         va_end(ap);
  816 }
  817 
  818 void
  819 aprint_verbose_ifnet(struct ifnet *ifp, const char *fmt, ...)
  820 {
  821         va_list ap;
  822 
  823         va_start(ap, fmt);
  824         aprint_verbose_internal(ifp->if_xname, fmt, ap);
  825         va_end(ap);
  826 }
  827 
  828 /*
  829  * aprint_debug: Send to console and log only if AB_DEBUG.
  830  */
  831 static void
  832 aprint_debug_internal(const char *prefix, const char *fmt, va_list ap)
  833 {
  834         int s;
  835 
  836         if ((boothowto & AB_DEBUG) == 0)
  837                 return;
  838 
  839         KPRINTF_MUTEX_ENTER(s);
  840 
  841         if (prefix)
  842                 kprintf_internal("%s: ", TOCONS | TOLOG, NULL, NULL, prefix);
  843         kprintf(fmt, TOCONS | TOLOG, NULL, NULL, ap);
  844 
  845         KPRINTF_MUTEX_EXIT(s);
  846 }
  847 
  848 void
  849 aprint_debug(const char *fmt, ...)
  850 {
  851         va_list ap;
  852 
  853         va_start(ap, fmt);
  854         aprint_debug_internal(NULL, fmt, ap);
  855         va_end(ap);
  856 }
  857 
  858 void
  859 aprint_debug_dev(device_t dv, const char *fmt, ...)
  860 {
  861         va_list ap;
  862 
  863         va_start(ap, fmt);
  864         aprint_debug_internal(device_xname(dv), fmt, ap);
  865         va_end(ap);
  866 }
  867 
  868 void
  869 aprint_debug_ifnet(struct ifnet *ifp, const char *fmt, ...)
  870 {
  871         va_list ap;
  872 
  873         va_start(ap, fmt);
  874         aprint_debug_internal(ifp->if_xname, fmt, ap);
  875         va_end(ap);
  876 }
  877 
  878 void
  879 printf_tolog(const char *fmt, ...)
  880 {
  881         va_list ap;
  882         int s;
  883 
  884         KPRINTF_MUTEX_ENTER(s);
  885 
  886         va_start(ap, fmt);
  887         (void)kprintf(fmt, TOLOG, NULL, NULL, ap);
  888         va_end(ap);
  889 
  890         KPRINTF_MUTEX_EXIT(s);
  891 }
  892 
  893 /*
  894  * printf_nolog: Like printf(), but does not send message to the log.
  895  */
  896 
  897 void
  898 printf_nolog(const char *fmt, ...)
  899 {
  900         va_list ap;
  901         int s;
  902 
  903         KPRINTF_MUTEX_ENTER(s);
  904 
  905         va_start(ap, fmt);
  906         kprintf(fmt, TOCONS, NULL, NULL, ap);
  907         va_end(ap);
  908 
  909         KPRINTF_MUTEX_EXIT(s);
  910 }
  911 
  912 /*
  913  * normal kernel printf functions: printf, vprintf, snprintf, vsnprintf
  914  */
  915 
  916 /*
  917  * printf: print a message to the console and the log
  918  */
  919 void
  920 printf(const char *fmt, ...)
  921 {
  922         va_list ap;
  923         int s;
  924 
  925         KPRINTF_MUTEX_ENTER(s);
  926 
  927         va_start(ap, fmt);
  928         kprintf(fmt, TOCONS | TOLOG, NULL, NULL, ap);
  929         va_end(ap);
  930 
  931         KPRINTF_MUTEX_EXIT(s);
  932 
  933         if (!panicstr)
  934                 logwakeup();
  935 }
  936 
  937 /*
  938  * vprintf: print a message to the console and the log [already have
  939  *      va_alist]
  940  */
  941 
  942 void
  943 vprintf(const char *fmt, va_list ap)
  944 {
  945         int s;
  946 
  947         KPRINTF_MUTEX_ENTER(s);
  948 
  949         kprintf(fmt, TOCONS | TOLOG, NULL, NULL, ap);
  950 
  951         KPRINTF_MUTEX_EXIT(s);
  952 
  953         if (!panicstr)
  954                 logwakeup();
  955 }
  956 
  957 /*
  958  * sprintf: print a message to a buffer
  959  */
  960 int
  961 sprintf(char *bf, const char *fmt, ...)
  962 {
  963         int retval;
  964         va_list ap;
  965 
  966         va_start(ap, fmt);
  967         retval = kprintf(fmt, TOBUFONLY, NULL, bf, ap);
  968         va_end(ap);
  969         *(bf + retval) = 0;     /* null terminate */
  970         return(retval);
  971 }
  972 
  973 /*
  974  * vsprintf: print a message to a buffer [already have va_alist]
  975  */
  976 
  977 int
  978 vsprintf(char *bf, const char *fmt, va_list ap)
  979 {
  980         int retval;
  981 
  982         retval = kprintf(fmt, TOBUFONLY, NULL, bf, ap);
  983         *(bf + retval) = 0;     /* null terminate */
  984         return (retval);
  985 }
  986 
  987 /*
  988  * snprintf: print a message to a buffer
  989  */
  990 int
  991 snprintf(char *bf, size_t size, const char *fmt, ...)
  992 {
  993         int retval;
  994         va_list ap;
  995         char *p;
  996 
  997         if (size < 1)
  998                 return (-1);
  999         p = bf + size - 1;
 1000         va_start(ap, fmt);
 1001         retval = kprintf(fmt, TOBUFONLY, &p, bf, ap);
 1002         va_end(ap);
 1003         *(p) = 0;       /* null terminate */
 1004         return(retval);
 1005 }
 1006 
 1007 /*
 1008  * vsnprintf: print a message to a buffer [already have va_alist]
 1009  */
 1010 int
 1011 vsnprintf(char *bf, size_t size, const char *fmt, va_list ap)
 1012 {
 1013         int retval;
 1014         char *p;
 1015 
 1016         if (size < 1)
 1017                 return (-1);
 1018         p = bf + size - 1;
 1019         retval = kprintf(fmt, TOBUFONLY, &p, bf, ap);
 1020         *(p) = 0;       /* null terminate */
 1021         return(retval);
 1022 }
 1023 
 1024 /*
 1025  * kprintf: scaled down version of printf(3).
 1026  *
 1027  * this version based on vfprintf() from libc which was derived from
 1028  * software contributed to Berkeley by Chris Torek.
 1029  *
 1030  * NOTE: The kprintf mutex must be held if we're going TOBUF or TOCONS!
 1031  */
 1032 
 1033 /*
 1034  * macros for converting digits to letters and vice versa
 1035  */
 1036 #define to_digit(c)     ((c) - '')
 1037 #define is_digit(c)     ((unsigned)to_digit(c) <= 9)
 1038 #define to_char(n)      ((n) + '')
 1039 
 1040 /*
 1041  * flags used during conversion.
 1042  */
 1043 #define ALT             0x001           /* alternate form */
 1044 #define HEXPREFIX       0x002           /* add 0x or 0X prefix */
 1045 #define LADJUST         0x004           /* left adjustment */
 1046 #define LONGDBL         0x008           /* long double; unimplemented */
 1047 #define LONGINT         0x010           /* long integer */
 1048 #define QUADINT         0x020           /* quad integer */
 1049 #define SHORTINT        0x040           /* short integer */
 1050 #define MAXINT          0x080           /* intmax_t */
 1051 #define PTRINT          0x100           /* intptr_t */
 1052 #define SIZEINT         0x200           /* size_t */
 1053 #define ZEROPAD         0x400           /* zero (as opposed to blank) pad */
 1054 #define FPT             0x800           /* Floating point number */
 1055 
 1056         /*
 1057          * To extend shorts properly, we need both signed and unsigned
 1058          * argument extraction methods.
 1059          */
 1060 #define SARG() \
 1061         (flags&MAXINT ? va_arg(ap, intmax_t) : \
 1062             flags&PTRINT ? va_arg(ap, intptr_t) : \
 1063             flags&SIZEINT ? va_arg(ap, ssize_t) : /* XXX */ \
 1064             flags&QUADINT ? va_arg(ap, quad_t) : \
 1065             flags&LONGINT ? va_arg(ap, long) : \
 1066             flags&SHORTINT ? (long)(short)va_arg(ap, int) : \
 1067             (long)va_arg(ap, int))
 1068 #define UARG() \
 1069         (flags&MAXINT ? va_arg(ap, uintmax_t) : \
 1070             flags&PTRINT ? va_arg(ap, uintptr_t) : \
 1071             flags&SIZEINT ? va_arg(ap, size_t) : \
 1072             flags&QUADINT ? va_arg(ap, u_quad_t) : \
 1073             flags&LONGINT ? va_arg(ap, u_long) : \
 1074             flags&SHORTINT ? (u_long)(u_short)va_arg(ap, int) : \
 1075             (u_long)va_arg(ap, u_int))
 1076 
 1077 #define KPRINTF_PUTCHAR(C) {                                            \
 1078         if (oflags == TOBUFONLY) {                                      \
 1079                 if ((vp != NULL) && (sbuf == tailp)) {                  \
 1080                         ret += 1;               /* indicate error */    \
 1081                         goto overflow;                                  \
 1082                 }                                                       \
 1083                 *sbuf++ = (C);                                          \
 1084         } else {                                                        \
 1085                 putchar((C), oflags, (struct tty *)vp);                 \
 1086         }                                                               \
 1087 }
 1088 
 1089 /*
 1090  * Guts of kernel printf.  Note, we already expect to be in a mutex!
 1091  */
 1092 int
 1093 kprintf(const char *fmt0, int oflags, void *vp, char *sbuf, va_list ap)
 1094 {
 1095         const char *fmt;        /* format string */
 1096         int ch;                 /* character from fmt */
 1097         int n;                  /* handy integer (short term usage) */
 1098         char *cp;               /* handy char pointer (short term usage) */
 1099         int flags;              /* flags as above */
 1100         int ret;                /* return value accumulator */
 1101         int width;              /* width from format (%8d), or 0 */
 1102         int prec;               /* precision from format (%.3d), or -1 */
 1103         char sign;              /* sign prefix (' ', '+', '-', or \0) */
 1104 
 1105         u_quad_t _uquad;        /* integer arguments %[diouxX] */
 1106         enum { OCT, DEC, HEX } base;/* base for [diouxX] conversion */
 1107         int dprec;              /* a copy of prec if [diouxX], 0 otherwise */
 1108         int realsz;             /* field size expanded by dprec */
 1109         int size;               /* size of converted field or string */
 1110         const char *xdigs;      /* digits for [xX] conversion */
 1111         char bf[KPRINTF_BUFSIZE]; /* space for %c, %[diouxX] */
 1112         char *tailp;            /* tail pointer for snprintf */
 1113 
 1114         tailp = NULL;   /* XXX: shutup gcc */
 1115         if (oflags == TOBUFONLY && (vp != NULL))
 1116                 tailp = *(char **)vp;
 1117 
 1118         cp = NULL;      /* XXX: shutup gcc */
 1119         size = 0;       /* XXX: shutup gcc */
 1120 
 1121         fmt = fmt0;
 1122         ret = 0;
 1123 
 1124         xdigs = NULL;           /* XXX: shut up gcc warning */
 1125 
 1126         /*
 1127          * Scan the format for conversions (`%' character).
 1128          */
 1129         for (;;) {
 1130                 while (*fmt != '%' && *fmt) {
 1131                         ret++;
 1132                         KPRINTF_PUTCHAR(*fmt++);
 1133                 }
 1134                 if (*fmt == 0)
 1135                         goto done;
 1136 
 1137                 fmt++;          /* skip over '%' */
 1138 
 1139                 flags = 0;
 1140                 dprec = 0;
 1141                 width = 0;
 1142                 prec = -1;
 1143                 sign = '\0';
 1144 
 1145 rflag:          ch = *fmt++;
 1146 reswitch:       switch (ch) {
 1147                 case ' ':
 1148                         /*
 1149                          * ``If the space and + flags both appear, the space
 1150                          * flag will be ignored.''
 1151                          *      -- ANSI X3J11
 1152                          */
 1153                         if (!sign)
 1154                                 sign = ' ';
 1155                         goto rflag;
 1156                 case '#':
 1157                         flags |= ALT;
 1158                         goto rflag;
 1159                 case '*':
 1160                         /*
 1161                          * ``A negative field width argument is taken as a
 1162                          * - flag followed by a positive field width.''
 1163                          *      -- ANSI X3J11
 1164                          * They don't exclude field widths read from args.
 1165                          */
 1166                         if ((width = va_arg(ap, int)) >= 0)
 1167                                 goto rflag;
 1168                         width = -width;
 1169                         /* FALLTHROUGH */
 1170                 case '-':
 1171                         flags |= LADJUST;
 1172                         goto rflag;
 1173                 case '+':
 1174                         sign = '+';
 1175                         goto rflag;
 1176                 case '.':
 1177                         if ((ch = *fmt++) == '*') {
 1178                                 n = va_arg(ap, int);
 1179                                 prec = n < 0 ? -1 : n;
 1180                                 goto rflag;
 1181                         }
 1182                         n = 0;
 1183                         while (is_digit(ch)) {
 1184                                 n = 10 * n + to_digit(ch);
 1185                                 ch = *fmt++;
 1186                         }
 1187                         prec = n < 0 ? -1 : n;
 1188                         goto reswitch;
 1189                 case '':
 1190                         /*
 1191                          * ``Note that 0 is taken as a flag, not as the
 1192                          * beginning of a field width.''
 1193                          *      -- ANSI X3J11
 1194                          */
 1195                         flags |= ZEROPAD;
 1196                         goto rflag;
 1197                 case '1': case '2': case '3': case '4':
 1198                 case '5': case '6': case '7': case '8': case '9':
 1199                         n = 0;
 1200                         do {
 1201                                 n = 10 * n + to_digit(ch);
 1202                                 ch = *fmt++;
 1203                         } while (is_digit(ch));
 1204                         width = n;
 1205                         goto reswitch;
 1206                 case 'h':
 1207                         flags |= SHORTINT;
 1208                         goto rflag;
 1209                 case 'j':
 1210                         flags |= MAXINT;
 1211                         goto rflag;
 1212                 case 'l':
 1213                         if (*fmt == 'l') {
 1214                                 fmt++;
 1215                                 flags |= QUADINT;
 1216                         } else {
 1217                                 flags |= LONGINT;
 1218                         }
 1219                         goto rflag;
 1220                 case 'q':
 1221                         flags |= QUADINT;
 1222                         goto rflag;
 1223                 case 't':
 1224                         flags |= PTRINT;
 1225                         goto rflag;
 1226                 case 'z':
 1227                         flags |= SIZEINT;
 1228                         goto rflag;
 1229                 case 'c':
 1230                         *(cp = bf) = va_arg(ap, int);
 1231                         size = 1;
 1232                         sign = '\0';
 1233                         break;
 1234                 case 'D':
 1235                         flags |= LONGINT;
 1236                         /*FALLTHROUGH*/
 1237                 case 'd':
 1238                 case 'i':
 1239                         _uquad = SARG();
 1240                         if ((quad_t)_uquad < 0) {
 1241                                 _uquad = -_uquad;
 1242                                 sign = '-';
 1243                         }
 1244                         base = DEC;
 1245                         goto number;
 1246                 case 'n':
 1247                         if (flags & MAXINT)
 1248                                 *va_arg(ap, intmax_t *) = ret;
 1249                         else if (flags & PTRINT)
 1250                                 *va_arg(ap, intptr_t *) = ret;
 1251                         else if (flags & SIZEINT)
 1252                                 *va_arg(ap, ssize_t *) = ret;
 1253                         else if (flags & QUADINT)
 1254                                 *va_arg(ap, quad_t *) = ret;
 1255                         else if (flags & LONGINT)
 1256                                 *va_arg(ap, long *) = ret;
 1257                         else if (flags & SHORTINT)
 1258                                 *va_arg(ap, short *) = ret;
 1259                         else
 1260                                 *va_arg(ap, int *) = ret;
 1261                         continue;       /* no output */
 1262                 case 'O':
 1263                         flags |= LONGINT;
 1264                         /*FALLTHROUGH*/
 1265                 case 'o':
 1266                         _uquad = UARG();
 1267                         base = OCT;
 1268                         goto nosign;
 1269                 case 'p':
 1270                         /*
 1271                          * ``The argument shall be a pointer to void.  The
 1272                          * value of the pointer is converted to a sequence
 1273                          * of printable characters, in an implementation-
 1274                          * defined manner.''
 1275                          *      -- ANSI X3J11
 1276                          */
 1277                         /* NOSTRICT */
 1278                         _uquad = (u_long)va_arg(ap, void *);
 1279                         base = HEX;
 1280                         xdigs = hexdigits;
 1281                         flags |= HEXPREFIX;
 1282                         ch = 'x';
 1283                         goto nosign;
 1284                 case 's':
 1285                         if ((cp = va_arg(ap, char *)) == NULL)
 1286                                 /*XXXUNCONST*/
 1287                                 cp = __UNCONST("(null)");
 1288                         if (prec >= 0) {
 1289                                 /*
 1290                                  * can't use strlen; can only look for the
 1291                                  * NUL in the first `prec' characters, and
 1292                                  * strlen() will go further.
 1293                                  */
 1294                                 char *p = memchr(cp, 0, prec);
 1295 
 1296                                 if (p != NULL) {
 1297                                         size = p - cp;
 1298                                         if (size > prec)
 1299                                                 size = prec;
 1300                                 } else
 1301                                         size = prec;
 1302                         } else
 1303                                 size = strlen(cp);
 1304                         sign = '\0';
 1305                         break;
 1306                 case 'U':
 1307                         flags |= LONGINT;
 1308                         /*FALLTHROUGH*/
 1309                 case 'u':
 1310                         _uquad = UARG();
 1311                         base = DEC;
 1312                         goto nosign;
 1313                 case 'X':
 1314                         xdigs = HEXDIGITS;
 1315                         goto hex;
 1316                 case 'x':
 1317                         xdigs = hexdigits;
 1318 hex:                    _uquad = UARG();
 1319                         base = HEX;
 1320                         /* leading 0x/X only if non-zero */
 1321                         if (flags & ALT && _uquad != 0)
 1322                                 flags |= HEXPREFIX;
 1323 
 1324                         /* unsigned conversions */
 1325 nosign:                 sign = '\0';
 1326                         /*
 1327                          * ``... diouXx conversions ... if a precision is
 1328                          * specified, the 0 flag will be ignored.''
 1329                          *      -- ANSI X3J11
 1330                          */
 1331 number:                 if ((dprec = prec) >= 0)
 1332                                 flags &= ~ZEROPAD;
 1333 
 1334                         /*
 1335                          * ``The result of converting a zero value with an
 1336                          * explicit precision of zero is no characters.''
 1337                          *      -- ANSI X3J11
 1338                          */
 1339                         cp = bf + KPRINTF_BUFSIZE;
 1340                         if (_uquad != 0 || prec != 0) {
 1341                                 /*
 1342                                  * Unsigned mod is hard, and unsigned mod
 1343                                  * by a constant is easier than that by
 1344                                  * a variable; hence this switch.
 1345                                  */
 1346                                 switch (base) {
 1347                                 case OCT:
 1348                                         do {
 1349                                                 *--cp = to_char(_uquad & 7);
 1350                                                 _uquad >>= 3;
 1351                                         } while (_uquad);
 1352                                         /* handle octal leading 0 */
 1353                                         if (flags & ALT && *cp != '')
 1354                                                 *--cp = '';
 1355                                         break;
 1356 
 1357                                 case DEC:
 1358                                         /* many numbers are 1 digit */
 1359                                         while (_uquad >= 10) {
 1360                                                 *--cp = to_char(_uquad % 10);
 1361                                                 _uquad /= 10;
 1362                                         }
 1363                                         *--cp = to_char(_uquad);
 1364                                         break;
 1365 
 1366                                 case HEX:
 1367                                         do {
 1368                                                 *--cp = xdigs[_uquad & 15];
 1369                                                 _uquad >>= 4;
 1370                                         } while (_uquad);
 1371                                         break;
 1372 
 1373                                 default:
 1374                                         /*XXXUNCONST*/
 1375                                         cp = __UNCONST("bug in kprintf: bad base");
 1376                                         size = strlen(cp);
 1377                                         goto skipsize;
 1378                                 }
 1379                         }
 1380                         size = bf + KPRINTF_BUFSIZE - cp;
 1381                 skipsize:
 1382                         break;
 1383                 default:        /* "%?" prints ?, unless ? is NUL */
 1384                         if (ch == '\0')
 1385                                 goto done;
 1386                         /* pretend it was %c with argument ch */
 1387                         cp = bf;
 1388                         *cp = ch;
 1389                         size = 1;
 1390                         sign = '\0';
 1391                         break;
 1392                 }
 1393 
 1394                 /*
 1395                  * All reasonable formats wind up here.  At this point, `cp'
 1396                  * points to a string which (if not flags&LADJUST) should be
 1397                  * padded out to `width' places.  If flags&ZEROPAD, it should
 1398                  * first be prefixed by any sign or other prefix; otherwise,
 1399                  * it should be blank padded before the prefix is emitted.
 1400                  * After any left-hand padding and prefixing, emit zeroes
 1401                  * required by a decimal [diouxX] precision, then print the
 1402                  * string proper, then emit zeroes required by any leftover
 1403                  * floating precision; finally, if LADJUST, pad with blanks.
 1404                  *
 1405                  * Compute actual size, so we know how much to pad.
 1406                  * size excludes decimal prec; realsz includes it.
 1407                  */
 1408                 realsz = dprec > size ? dprec : size;
 1409                 if (sign)
 1410                         realsz++;
 1411                 else if (flags & HEXPREFIX)
 1412                         realsz+= 2;
 1413 
 1414                 /* adjust ret */
 1415                 ret += width > realsz ? width : realsz;
 1416 
 1417                 /* right-adjusting blank padding */
 1418                 if ((flags & (LADJUST|ZEROPAD)) == 0) {
 1419                         n = width - realsz;
 1420                         while (n-- > 0)
 1421                                 KPRINTF_PUTCHAR(' ');
 1422                 }
 1423 
 1424                 /* prefix */
 1425                 if (sign) {
 1426                         KPRINTF_PUTCHAR(sign);
 1427                 } else if (flags & HEXPREFIX) {
 1428                         KPRINTF_PUTCHAR('');
 1429                         KPRINTF_PUTCHAR(ch);
 1430                 }
 1431 
 1432                 /* right-adjusting zero padding */
 1433                 if ((flags & (LADJUST|ZEROPAD)) == ZEROPAD) {
 1434                         n = width - realsz;
 1435                         while (n-- > 0)
 1436                                 KPRINTF_PUTCHAR('');
 1437                 }
 1438 
 1439                 /* leading zeroes from decimal precision */
 1440                 n = dprec - size;
 1441                 while (n-- > 0)
 1442                         KPRINTF_PUTCHAR('');
 1443 
 1444                 /* the string or number proper */
 1445                 while (size--)
 1446                         KPRINTF_PUTCHAR(*cp++);
 1447                 /* left-adjusting padding (always blank) */
 1448                 if (flags & LADJUST) {
 1449                         n = width - realsz;
 1450                         while (n-- > 0)
 1451                                 KPRINTF_PUTCHAR(' ');
 1452                 }
 1453         }
 1454 
 1455 done:
 1456         if ((oflags == TOBUFONLY) && (vp != NULL))
 1457                 *(char **)vp = sbuf;
 1458         (*v_flush)();
 1459 overflow:
 1460         return (ret);
 1461         /* NOTREACHED */
 1462 }

Cache object: d2894209ed04a78ac01051d0b311bbbd


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.