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-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-2  -  FREEBSD-11-1  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-4  -  FREEBSD-10-3  -  FREEBSD-10-2  -  FREEBSD-10-1  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-3  -  FREEBSD-9-2  -  FREEBSD-9-1  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-4  -  FREEBSD-8-3  -  FREEBSD-8-2  -  FREEBSD-8-1  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-4  -  FREEBSD-7-3  -  FREEBSD-7-2  -  FREEBSD-7-1  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-4  -  FREEBSD-6-3  -  FREEBSD-6-2  -  FREEBSD-6-1  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-5  -  FREEBSD-5-4  -  FREEBSD-5-3  -  FREEBSD-5-2  -  FREEBSD-5-1  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  linux-2.6  -  linux-2.4.22  -  MK83  -  MK84  -  PLAN9  -  DFBSD  -  NETBSD  -  NETBSD5  -  NETBSD4  -  NETBSD3  -  NETBSD20  -  OPENBSD  -  xnu-517  -  xnu-792  -  xnu-792.6.70  -  xnu-1228  -  xnu-1456.1.26  -  xnu-1699.24.8  -  xnu-2050.18.24  -  OPENSOLARIS  -  minix-3-1-1 
SearchContext: -  none  -  3  -  10 

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

Cache object: 34da6ae9c1d2f9cd05433ac5f6cf6da6


[ 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.