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

Cache object: 7af0afcfb4f1ebed300d969e0e313706


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