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.96 2005/02/26 21:34:55 perry 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.96 2005/02/26 21:34:55 perry 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         if (db_tee_msgbuf) {
  550                 va_start(ap, fmt);
  551                 kprintf(fmt, TOLOG, NULL, NULL, ap);
  552                 va_end(ap);
  553         };
  554 }
  555 
  556 void
  557 db_vprintf(fmt, ap)
  558         const char *fmt;
  559         va_list ap;
  560 {
  561 
  562         /* No mutex needed; DDB pauses all processors. */
  563         kprintf(fmt, TODDB, NULL, NULL, ap);
  564         if (db_tee_msgbuf)
  565                 kprintf(fmt, TOLOG, NULL, NULL, ap);
  566 }
  567 
  568 #endif /* DDB */
  569 
  570 /*
  571  * Device autoconfiguration printf routines.  These change their
  572  * behavior based on the AB_* flags in boothowto.  If AB_SILENT
  573  * is set, messages never go to the console (but they still always
  574  * go to the log).  AB_VERBOSE overrides AB_SILENT.
  575  */
  576 
  577 /*
  578  * aprint_normal: Send to console unless AB_QUIET.  Always goes
  579  * to the log.
  580  */
  581 void
  582 aprint_normal(const char *fmt, ...)
  583 {
  584         va_list ap;
  585         int s, flags = TOLOG;
  586 
  587         if ((boothowto & (AB_SILENT|AB_QUIET)) == 0 ||
  588             (boothowto & AB_VERBOSE) != 0)
  589                 flags |= TOCONS;
  590 
  591         KPRINTF_MUTEX_ENTER(s);
  592 
  593         va_start(ap, fmt);
  594         kprintf(fmt, flags, NULL, NULL, ap);
  595         va_end(ap);
  596 
  597         KPRINTF_MUTEX_EXIT(s);
  598 
  599         if (!panicstr)
  600                 logwakeup();
  601 }
  602 
  603 /*
  604  * aprint_error: Send to console unless AB_QUIET.  Always goes
  605  * to the log.  Also counts the number of times called so other
  606  * parts of the kernel can report the number of errors during a
  607  * given phase of system startup.
  608  */
  609 static int aprint_error_count;
  610 
  611 int
  612 aprint_get_error_count(void)
  613 {
  614         int count, s;
  615 
  616         KPRINTF_MUTEX_ENTER(s);
  617 
  618         count = aprint_error_count;
  619         aprint_error_count = 0;
  620 
  621         KPRINTF_MUTEX_EXIT(s);
  622 
  623         return (count);
  624 }
  625 
  626 void
  627 aprint_error(const char *fmt, ...)
  628 {
  629         va_list ap;
  630         int s, flags = TOLOG;
  631 
  632         if ((boothowto & (AB_SILENT|AB_QUIET)) == 0 ||
  633             (boothowto & AB_VERBOSE) != 0)
  634                 flags |= TOCONS;
  635 
  636         KPRINTF_MUTEX_ENTER(s);
  637 
  638         aprint_error_count++;
  639 
  640         va_start(ap, fmt);
  641         kprintf(fmt, flags, NULL, NULL, ap);
  642         va_end(ap);
  643 
  644         KPRINTF_MUTEX_EXIT(s);
  645 
  646         if (!panicstr)
  647                 logwakeup();
  648 }
  649 
  650 /*
  651  * aprint_naive: Send to console only if AB_QUIET.  Never goes
  652  * to the log.
  653  */
  654 void
  655 aprint_naive(const char *fmt, ...)
  656 {
  657         va_list ap;
  658         int s;
  659 
  660         if ((boothowto & (AB_QUIET|AB_SILENT|AB_VERBOSE)) == AB_QUIET) {
  661                 KPRINTF_MUTEX_ENTER(s);
  662 
  663                 va_start(ap, fmt);
  664                 kprintf(fmt, TOCONS, NULL, NULL, ap);
  665                 va_end(ap);
  666 
  667                 KPRINTF_MUTEX_EXIT(s);
  668         }
  669 }
  670 
  671 /*
  672  * aprint_verbose: Send to console only if AB_VERBOSE.  Always
  673  * goes to the log.
  674  */
  675 void
  676 aprint_verbose(const char *fmt, ...)
  677 {
  678         va_list ap;
  679         int s, flags = TOLOG;
  680 
  681         if (boothowto & AB_VERBOSE)
  682                 flags |= TOCONS;
  683 
  684         KPRINTF_MUTEX_ENTER(s);
  685 
  686         va_start(ap, fmt);
  687         kprintf(fmt, flags, NULL, NULL, ap);
  688         va_end(ap);
  689 
  690         KPRINTF_MUTEX_EXIT(s);
  691 
  692         if (!panicstr)
  693                 logwakeup();
  694 }
  695 
  696 /*
  697  * aprint_debug: Send to console and log only if AB_DEBUG.
  698  */
  699 void
  700 aprint_debug(const char *fmt, ...)
  701 {
  702         va_list ap;
  703         int s;
  704 
  705         if (boothowto & AB_DEBUG) {
  706                 KPRINTF_MUTEX_ENTER(s);
  707 
  708                 va_start(ap, fmt);
  709                 kprintf(fmt, TOCONS | TOLOG, NULL, NULL, ap);
  710                 va_end(ap);
  711 
  712                 KPRINTF_MUTEX_EXIT(s);
  713         }
  714 }
  715 
  716 /*
  717  * printf_nolog: Like printf(), but does not send message to the log.
  718  */
  719 
  720 void
  721 printf_nolog(const char *fmt, ...)
  722 {
  723         va_list ap;
  724         int s;
  725 
  726         KPRINTF_MUTEX_ENTER(s);
  727 
  728         va_start(ap, fmt);
  729         kprintf(fmt, TOCONS, NULL, NULL, ap);
  730         va_end(ap);
  731 
  732         KPRINTF_MUTEX_EXIT(s);
  733 }
  734 
  735 /*
  736  * normal kernel printf functions: printf, vprintf, snprintf, vsnprintf
  737  */
  738 
  739 /*
  740  * printf: print a message to the console and the log
  741  */
  742 void
  743 printf(const char *fmt, ...)
  744 {
  745         va_list ap;
  746         int s;
  747 
  748         KPRINTF_MUTEX_ENTER(s);
  749 
  750         va_start(ap, fmt);
  751         kprintf(fmt, TOCONS | TOLOG, NULL, NULL, ap);
  752         va_end(ap);
  753 
  754         KPRINTF_MUTEX_EXIT(s);
  755 
  756         if (!panicstr)
  757                 logwakeup();
  758 }
  759 
  760 /*
  761  * vprintf: print a message to the console and the log [already have
  762  *      va_alist]
  763  */
  764 
  765 void
  766 vprintf(fmt, ap)
  767         const char *fmt;
  768         va_list ap;
  769 {
  770         int s;
  771 
  772         KPRINTF_MUTEX_ENTER(s);
  773 
  774         kprintf(fmt, TOCONS | TOLOG, NULL, NULL, ap);
  775 
  776         KPRINTF_MUTEX_EXIT(s);
  777 
  778         if (!panicstr)
  779                 logwakeup();
  780 }
  781 
  782 /*
  783  * sprintf: print a message to a buffer
  784  */
  785 int
  786 sprintf(char *buf, const char *fmt, ...)
  787 {
  788         int retval;
  789         va_list ap;
  790 
  791         va_start(ap, fmt);
  792         retval = kprintf(fmt, TOBUFONLY, NULL, buf, ap);
  793         va_end(ap);
  794         *(buf + retval) = 0;    /* null terminate */
  795         return(retval);
  796 }
  797 
  798 /*
  799  * vsprintf: print a message to a buffer [already have va_alist]
  800  */
  801 
  802 int
  803 vsprintf(buf, fmt, ap)
  804         char *buf;
  805         const char *fmt;
  806         va_list ap;
  807 {
  808         int retval;
  809 
  810         retval = kprintf(fmt, TOBUFONLY, NULL, buf, ap);
  811         *(buf + retval) = 0;    /* null terminate */
  812         return (retval);
  813 }
  814 
  815 /*
  816  * snprintf: print a message to a buffer
  817  */
  818 int
  819 snprintf(char *buf, size_t size, const char *fmt, ...)
  820 {
  821         int retval;
  822         va_list ap;
  823         char *p;
  824 
  825         if (size < 1)
  826                 return (-1);
  827         p = buf + size - 1;
  828         va_start(ap, fmt);
  829         retval = kprintf(fmt, TOBUFONLY, &p, buf, ap);
  830         va_end(ap);
  831         *(p) = 0;       /* null terminate */
  832         return(retval);
  833 }
  834 
  835 /*
  836  * vsnprintf: print a message to a buffer [already have va_alist]
  837  */
  838 int
  839 vsnprintf(buf, size, fmt, ap)
  840         char *buf;
  841         size_t size;
  842         const char *fmt;
  843         va_list ap;
  844 {
  845         int retval;
  846         char *p;
  847 
  848         if (size < 1)
  849                 return (-1);
  850         p = buf + size - 1;
  851         retval = kprintf(fmt, TOBUFONLY, &p, buf, ap);
  852         *(p) = 0;       /* null terminate */
  853         return(retval);
  854 }
  855 
  856 /*
  857  * bitmask_snprintf: print an interpreted bitmask to a buffer
  858  *
  859  * => returns pointer to the buffer
  860  */
  861 char *
  862 bitmask_snprintf(val, p, buf, buflen)
  863         u_quad_t val;
  864         const char *p;
  865         char *buf;
  866         size_t buflen;
  867 {
  868         char *bp, *q;
  869         size_t left;
  870         char *sbase, snbuf[KPRINTF_BUFSIZE];
  871         int base, bit, ch, len, sep;
  872         u_quad_t field;
  873 
  874         bp = buf;
  875         memset(buf, 0, buflen);
  876 
  877         /*
  878          * Always leave room for the trailing NULL.
  879          */
  880         left = buflen - 1;
  881 
  882         /*
  883          * Print the value into the buffer.  Abort if there's not
  884          * enough room.
  885          */
  886         if (buflen < KPRINTF_BUFSIZE)
  887                 return (buf);
  888 
  889         ch = *p++;
  890         base = ch != '\177' ? ch : *p++;
  891         sbase = base == 8 ? "%qo" : base == 10 ? "%qd" : base == 16 ? "%qx" : 0;
  892         if (sbase == 0)
  893                 return (buf);   /* punt if not oct, dec, or hex */
  894 
  895         snprintf(snbuf, sizeof(snbuf), sbase, val);
  896         for (q = snbuf ; *q ; q++) {
  897                 *bp++ = *q;
  898                 left--;
  899         }
  900 
  901         /*
  902          * If the value we printed was 0 and we're using the old-style format,
  903          * or if we don't have room for "<x>", we're done.
  904          */
  905         if (((val == 0) && (ch != '\177')) || left < 3)
  906                 return (buf);
  907 
  908 #define PUTBYTE(b, c, l) do {   \
  909         *(b)++ = (c);           \
  910         if (--(l) == 0)         \
  911                 goto out;       \
  912 } while (/*CONSTCOND*/ 0)
  913 #define PUTSTR(b, p, l) do {            \
  914         int c;                          \
  915         while ((c = *(p)++) != 0) {     \
  916                 *(b)++ = c;             \
  917                 if (--(l) == 0)         \
  918                         goto out;       \
  919         }                               \
  920 } while (/*CONSTCOND*/ 0)
  921 
  922         /*
  923          * Chris Torek's new bitmask format is identified by a leading \177
  924          */
  925         sep = '<';
  926         if (ch != '\177') {
  927                 /* old (standard) format. */
  928                 for (;(bit = *p++) != 0;) {
  929                         if (val & (1 << (bit - 1))) {
  930                                 PUTBYTE(bp, sep, left);
  931                                 for (; (ch = *p) > ' '; ++p) {
  932                                         PUTBYTE(bp, ch, left);
  933                                 }
  934                                 sep = ',';
  935                         } else
  936                                 for (; *p > ' '; ++p)
  937                                         continue;
  938                 }
  939         } else {
  940                 /* new quad-capable format; also does fields. */
  941                 field = val;
  942                 while ((ch = *p++) != '\0') {
  943                         bit = *p++;     /* now 0-origin */
  944                         switch (ch) {
  945                         case 'b':
  946                                 if (((u_int)(val >> bit) & 1) == 0)
  947                                         goto skip;
  948                                 PUTBYTE(bp, sep, left);
  949                                 PUTSTR(bp, p, left);
  950                                 sep = ',';
  951                                 break;
  952                         case 'f':
  953                         case 'F':
  954                                 len = *p++;     /* field length */
  955                                 field = (val >> bit) & ((1ULL << len) - 1);
  956                                 if (ch == 'F')  /* just extract */
  957                                         break;
  958                                 PUTBYTE(bp, sep, left);
  959                                 sep = ',';
  960                                 PUTSTR(bp, p, left);
  961                                 PUTBYTE(bp, '=', left);
  962                                 sprintf(snbuf, sbase, field);
  963                                 q = snbuf; PUTSTR(bp, q, left);
  964                                 break;
  965                         case '=':
  966                         case ':':
  967                                 /*
  968                                  * Here "bit" is actually a value instead,
  969                                  * to be compared against the last field.
  970                                  * This only works for values in [0..255],
  971                                  * of course.
  972                                  */
  973                                 if ((int)field != bit)
  974                                         goto skip;
  975                                 if (ch == '=')
  976                                         PUTBYTE(bp, '=', left);
  977                                 PUTSTR(bp, p, left);
  978                                 break;
  979                         default:
  980                         skip:
  981                                 while (*p++ != '\0')
  982                                         continue;
  983                                 break;
  984                         }
  985                 }
  986         }
  987         if (sep != '<')
  988                 PUTBYTE(bp, '>', left);
  989 
  990 out:
  991         return (buf);
  992 
  993 #undef PUTBYTE
  994 #undef PUTSTR
  995 }
  996 
  997 /*
  998  * kprintf: scaled down version of printf(3).
  999  *
 1000  * this version based on vfprintf() from libc which was derived from
 1001  * software contributed to Berkeley by Chris Torek.
 1002  *
 1003  * NOTE: The kprintf mutex must be held if we're going TOBUF or TOCONS!
 1004  */
 1005 
 1006 /*
 1007  * macros for converting digits to letters and vice versa
 1008  */
 1009 #define to_digit(c)     ((c) - '')
 1010 #define is_digit(c)     ((unsigned)to_digit(c) <= 9)
 1011 #define to_char(n)      ((n) + '')
 1012 
 1013 /*
 1014  * flags used during conversion.
 1015  */
 1016 #define ALT             0x001           /* alternate form */
 1017 #define HEXPREFIX       0x002           /* add 0x or 0X prefix */
 1018 #define LADJUST         0x004           /* left adjustment */
 1019 #define LONGDBL         0x008           /* long double; unimplemented */
 1020 #define LONGINT         0x010           /* long integer */
 1021 #define QUADINT         0x020           /* quad integer */
 1022 #define SHORTINT        0x040           /* short integer */
 1023 #define MAXINT          0x080           /* intmax_t */
 1024 #define PTRINT          0x100           /* intptr_t */
 1025 #define SIZEINT         0x200           /* size_t */
 1026 #define ZEROPAD         0x400           /* zero (as opposed to blank) pad */
 1027 #define FPT             0x800           /* Floating point number */
 1028 
 1029         /*
 1030          * To extend shorts properly, we need both signed and unsigned
 1031          * argument extraction methods.
 1032          */
 1033 #define SARG() \
 1034         (flags&MAXINT ? va_arg(ap, intmax_t) : \
 1035             flags&PTRINT ? va_arg(ap, intptr_t) : \
 1036             flags&SIZEINT ? va_arg(ap, ssize_t) : /* XXX */ \
 1037             flags&QUADINT ? va_arg(ap, quad_t) : \
 1038             flags&LONGINT ? va_arg(ap, long) : \
 1039             flags&SHORTINT ? (long)(short)va_arg(ap, int) : \
 1040             (long)va_arg(ap, int))
 1041 #define UARG() \
 1042         (flags&MAXINT ? va_arg(ap, uintmax_t) : \
 1043             flags&PTRINT ? va_arg(ap, uintptr_t) : \
 1044             flags&SIZEINT ? va_arg(ap, size_t) : \
 1045             flags&QUADINT ? va_arg(ap, u_quad_t) : \
 1046             flags&LONGINT ? va_arg(ap, u_long) : \
 1047             flags&SHORTINT ? (u_long)(u_short)va_arg(ap, int) : \
 1048             (u_long)va_arg(ap, u_int))
 1049 
 1050 #define KPRINTF_PUTCHAR(C) {                                            \
 1051         if (oflags == TOBUFONLY) {                                      \
 1052                 if ((vp != NULL) && (sbuf == tailp)) {                  \
 1053                         ret += 1;               /* indicate error */    \
 1054                         goto overflow;                                  \
 1055                 }                                                       \
 1056                 *sbuf++ = (C);                                          \
 1057         } else {                                                        \
 1058                 putchar((C), oflags, (struct tty *)vp);                 \
 1059         }                                                               \
 1060 }
 1061 
 1062 /*
 1063  * Guts of kernel printf.  Note, we already expect to be in a mutex!
 1064  */
 1065 int
 1066 kprintf(fmt0, oflags, vp, sbuf, ap)
 1067         const char *fmt0;
 1068         int oflags;
 1069         void *vp;
 1070         char *sbuf;
 1071         va_list ap;
 1072 {
 1073         char *fmt;              /* format string */
 1074         int ch;                 /* character from fmt */
 1075         int n;                  /* handy integer (short term usage) */
 1076         char *cp;               /* handy char pointer (short term usage) */
 1077         int flags;              /* flags as above */
 1078         int ret;                /* return value accumulator */
 1079         int width;              /* width from format (%8d), or 0 */
 1080         int prec;               /* precision from format (%.3d), or -1 */
 1081         char sign;              /* sign prefix (' ', '+', '-', or \0) */
 1082 
 1083         u_quad_t _uquad;        /* integer arguments %[diouxX] */
 1084         enum { OCT, DEC, HEX } base;/* base for [diouxX] conversion */
 1085         int dprec;              /* a copy of prec if [diouxX], 0 otherwise */
 1086         int realsz;             /* field size expanded by dprec */
 1087         int size;               /* size of converted field or string */
 1088         char *xdigs;            /* digits for [xX] conversion */
 1089         char buf[KPRINTF_BUFSIZE]; /* space for %c, %[diouxX] */
 1090         char *tailp;            /* tail pointer for snprintf */
 1091 
 1092         tailp = NULL;   /* XXX: shutup gcc */
 1093         if (oflags == TOBUFONLY && (vp != NULL))
 1094                 tailp = *(char **)vp;
 1095 
 1096         cp = NULL;      /* XXX: shutup gcc */
 1097         size = 0;       /* XXX: shutup gcc */
 1098 
 1099         fmt = (char *)fmt0;
 1100         ret = 0;
 1101 
 1102         xdigs = NULL;           /* XXX: shut up gcc warning */
 1103 
 1104         /*
 1105          * Scan the format for conversions (`%' character).
 1106          */
 1107         for (;;) {
 1108                 while (*fmt != '%' && *fmt) {
 1109                         ret++;
 1110                         KPRINTF_PUTCHAR(*fmt++);
 1111                 }
 1112                 if (*fmt == 0)
 1113                         goto done;
 1114 
 1115                 fmt++;          /* skip over '%' */
 1116 
 1117                 flags = 0;
 1118                 dprec = 0;
 1119                 width = 0;
 1120                 prec = -1;
 1121                 sign = '\0';
 1122 
 1123 rflag:          ch = *fmt++;
 1124 reswitch:       switch (ch) {
 1125                 case ' ':
 1126                         /*
 1127                          * ``If the space and + flags both appear, the space
 1128                          * flag will be ignored.''
 1129                          *      -- ANSI X3J11
 1130                          */
 1131                         if (!sign)
 1132                                 sign = ' ';
 1133                         goto rflag;
 1134                 case '#':
 1135                         flags |= ALT;
 1136                         goto rflag;
 1137                 case '*':
 1138                         /*
 1139                          * ``A negative field width argument is taken as a
 1140                          * - flag followed by a positive field width.''
 1141                          *      -- ANSI X3J11
 1142                          * They don't exclude field widths read from args.
 1143                          */
 1144                         if ((width = va_arg(ap, int)) >= 0)
 1145                                 goto rflag;
 1146                         width = -width;
 1147                         /* FALLTHROUGH */
 1148                 case '-':
 1149                         flags |= LADJUST;
 1150                         goto rflag;
 1151                 case '+':
 1152                         sign = '+';
 1153                         goto rflag;
 1154                 case '.':
 1155                         if ((ch = *fmt++) == '*') {
 1156                                 n = va_arg(ap, int);
 1157                                 prec = n < 0 ? -1 : n;
 1158                                 goto rflag;
 1159                         }
 1160                         n = 0;
 1161                         while (is_digit(ch)) {
 1162                                 n = 10 * n + to_digit(ch);
 1163                                 ch = *fmt++;
 1164                         }
 1165                         prec = n < 0 ? -1 : n;
 1166                         goto reswitch;
 1167                 case '':
 1168                         /*
 1169                          * ``Note that 0 is taken as a flag, not as the
 1170                          * beginning of a field width.''
 1171                          *      -- ANSI X3J11
 1172                          */
 1173                         flags |= ZEROPAD;
 1174                         goto rflag;
 1175                 case '1': case '2': case '3': case '4':
 1176                 case '5': case '6': case '7': case '8': case '9':
 1177                         n = 0;
 1178                         do {
 1179                                 n = 10 * n + to_digit(ch);
 1180                                 ch = *fmt++;
 1181                         } while (is_digit(ch));
 1182                         width = n;
 1183                         goto reswitch;
 1184                 case 'h':
 1185                         flags |= SHORTINT;
 1186                         goto rflag;
 1187                 case 'j':
 1188                         flags |= MAXINT;
 1189                         goto rflag;
 1190                 case 'l':
 1191                         if (*fmt == 'l') {
 1192                                 fmt++;
 1193                                 flags |= QUADINT;
 1194                         } else {
 1195                                 flags |= LONGINT;
 1196                         }
 1197                         goto rflag;
 1198                 case 'q':
 1199                         flags |= QUADINT;
 1200                         goto rflag;
 1201                 case 't':
 1202                         flags |= PTRINT;
 1203                         goto rflag;
 1204                 case 'z':
 1205                         flags |= SIZEINT;
 1206                         goto rflag;
 1207                 case 'c':
 1208                         *(cp = buf) = va_arg(ap, int);
 1209                         size = 1;
 1210                         sign = '\0';
 1211                         break;
 1212                 case 'D':
 1213                         flags |= LONGINT;
 1214                         /*FALLTHROUGH*/
 1215                 case 'd':
 1216                 case 'i':
 1217                         _uquad = SARG();
 1218                         if ((quad_t)_uquad < 0) {
 1219                                 _uquad = -_uquad;
 1220                                 sign = '-';
 1221                         }
 1222                         base = DEC;
 1223                         goto number;
 1224                 case 'n':
 1225                         if (flags & MAXINT)
 1226                                 *va_arg(ap, intmax_t *) = ret;
 1227                         else if (flags & PTRINT)
 1228                                 *va_arg(ap, intptr_t *) = ret;
 1229                         else if (flags & SIZEINT)
 1230                                 *va_arg(ap, ssize_t *) = ret;
 1231                         else if (flags & QUADINT)
 1232                                 *va_arg(ap, quad_t *) = ret;
 1233                         else if (flags & LONGINT)
 1234                                 *va_arg(ap, long *) = ret;
 1235                         else if (flags & SHORTINT)
 1236                                 *va_arg(ap, short *) = ret;
 1237                         else
 1238                                 *va_arg(ap, int *) = ret;
 1239                         continue;       /* no output */
 1240                 case 'O':
 1241                         flags |= LONGINT;
 1242                         /*FALLTHROUGH*/
 1243                 case 'o':
 1244                         _uquad = UARG();
 1245                         base = OCT;
 1246                         goto nosign;
 1247                 case 'p':
 1248                         /*
 1249                          * ``The argument shall be a pointer to void.  The
 1250                          * value of the pointer is converted to a sequence
 1251                          * of printable characters, in an implementation-
 1252                          * defined manner.''
 1253                          *      -- ANSI X3J11
 1254                          */
 1255                         /* NOSTRICT */
 1256                         _uquad = (u_long)va_arg(ap, void *);
 1257                         base = HEX;
 1258                         xdigs = "0123456789abcdef";
 1259                         flags |= HEXPREFIX;
 1260                         ch = 'x';
 1261                         goto nosign;
 1262                 case 's':
 1263                         if ((cp = va_arg(ap, char *)) == NULL)
 1264                                 cp = "(null)";
 1265                         if (prec >= 0) {
 1266                                 /*
 1267                                  * can't use strlen; can only look for the
 1268                                  * NUL in the first `prec' characters, and
 1269                                  * strlen() will go further.
 1270                                  */
 1271                                 char *p = memchr(cp, 0, prec);
 1272 
 1273                                 if (p != NULL) {
 1274                                         size = p - cp;
 1275                                         if (size > prec)
 1276                                                 size = prec;
 1277                                 } else
 1278                                         size = prec;
 1279                         } else
 1280                                 size = strlen(cp);
 1281                         sign = '\0';
 1282                         break;
 1283                 case 'U':
 1284                         flags |= LONGINT;
 1285                         /*FALLTHROUGH*/
 1286                 case 'u':
 1287                         _uquad = UARG();
 1288                         base = DEC;
 1289                         goto nosign;
 1290                 case 'X':
 1291                         xdigs = "0123456789ABCDEF";
 1292                         goto hex;
 1293                 case 'x':
 1294                         xdigs = "0123456789abcdef";
 1295 hex:                    _uquad = UARG();
 1296                         base = HEX;
 1297                         /* leading 0x/X only if non-zero */
 1298                         if (flags & ALT && _uquad != 0)
 1299                                 flags |= HEXPREFIX;
 1300 
 1301                         /* unsigned conversions */
 1302 nosign:                 sign = '\0';
 1303                         /*
 1304                          * ``... diouXx conversions ... if a precision is
 1305                          * specified, the 0 flag will be ignored.''
 1306                          *      -- ANSI X3J11
 1307                          */
 1308 number:                 if ((dprec = prec) >= 0)
 1309                                 flags &= ~ZEROPAD;
 1310 
 1311                         /*
 1312                          * ``The result of converting a zero value with an
 1313                          * explicit precision of zero is no characters.''
 1314                          *      -- ANSI X3J11
 1315                          */
 1316                         cp = buf + KPRINTF_BUFSIZE;
 1317                         if (_uquad != 0 || prec != 0) {
 1318                                 /*
 1319                                  * Unsigned mod is hard, and unsigned mod
 1320                                  * by a constant is easier than that by
 1321                                  * a variable; hence this switch.
 1322                                  */
 1323                                 switch (base) {
 1324                                 case OCT:
 1325                                         do {
 1326                                                 *--cp = to_char(_uquad & 7);
 1327                                                 _uquad >>= 3;
 1328                                         } while (_uquad);
 1329                                         /* handle octal leading 0 */
 1330                                         if (flags & ALT && *cp != '')
 1331                                                 *--cp = '';
 1332                                         break;
 1333 
 1334                                 case DEC:
 1335                                         /* many numbers are 1 digit */
 1336                                         while (_uquad >= 10) {
 1337                                                 *--cp = to_char(_uquad % 10);
 1338                                                 _uquad /= 10;
 1339                                         }
 1340                                         *--cp = to_char(_uquad);
 1341                                         break;
 1342 
 1343                                 case HEX:
 1344                                         do {
 1345                                                 *--cp = xdigs[_uquad & 15];
 1346                                                 _uquad >>= 4;
 1347                                         } while (_uquad);
 1348                                         break;
 1349 
 1350                                 default:
 1351                                         cp = "bug in kprintf: bad base";
 1352                                         size = strlen(cp);
 1353                                         goto skipsize;
 1354                                 }
 1355                         }
 1356                         size = buf + KPRINTF_BUFSIZE - cp;
 1357                 skipsize:
 1358                         break;
 1359                 default:        /* "%?" prints ?, unless ? is NUL */
 1360                         if (ch == '\0')
 1361                                 goto done;
 1362                         /* pretend it was %c with argument ch */
 1363                         cp = buf;
 1364                         *cp = ch;
 1365                         size = 1;
 1366                         sign = '\0';
 1367                         break;
 1368                 }
 1369 
 1370                 /*
 1371                  * All reasonable formats wind up here.  At this point, `cp'
 1372                  * points to a string which (if not flags&LADJUST) should be
 1373                  * padded out to `width' places.  If flags&ZEROPAD, it should
 1374                  * first be prefixed by any sign or other prefix; otherwise,
 1375                  * it should be blank padded before the prefix is emitted.
 1376                  * After any left-hand padding and prefixing, emit zeroes
 1377                  * required by a decimal [diouxX] precision, then print the
 1378                  * string proper, then emit zeroes required by any leftover
 1379                  * floating precision; finally, if LADJUST, pad with blanks.
 1380                  *
 1381                  * Compute actual size, so we know how much to pad.
 1382                  * size excludes decimal prec; realsz includes it.
 1383                  */
 1384                 realsz = dprec > size ? dprec : size;
 1385                 if (sign)
 1386                         realsz++;
 1387                 else if (flags & HEXPREFIX)
 1388                         realsz+= 2;
 1389 
 1390                 /* adjust ret */
 1391                 ret += width > realsz ? width : realsz;
 1392 
 1393                 /* right-adjusting blank padding */
 1394                 if ((flags & (LADJUST|ZEROPAD)) == 0) {
 1395                         n = width - realsz;
 1396                         while (n-- > 0)
 1397                                 KPRINTF_PUTCHAR(' ');
 1398                 }
 1399 
 1400                 /* prefix */
 1401                 if (sign) {
 1402                         KPRINTF_PUTCHAR(sign);
 1403                 } else if (flags & HEXPREFIX) {
 1404                         KPRINTF_PUTCHAR('');
 1405                         KPRINTF_PUTCHAR(ch);
 1406                 }
 1407 
 1408                 /* right-adjusting zero padding */
 1409                 if ((flags & (LADJUST|ZEROPAD)) == ZEROPAD) {
 1410                         n = width - realsz;
 1411                         while (n-- > 0)
 1412                                 KPRINTF_PUTCHAR('');
 1413                 }
 1414 
 1415                 /* leading zeroes from decimal precision */
 1416                 n = dprec - size;
 1417                 while (n-- > 0)
 1418                         KPRINTF_PUTCHAR('');
 1419 
 1420                 /* the string or number proper */
 1421                 while (size--)
 1422                         KPRINTF_PUTCHAR(*cp++);
 1423                 /* left-adjusting padding (always blank) */
 1424                 if (flags & LADJUST) {
 1425                         n = width - realsz;
 1426                         while (n-- > 0)
 1427                                 KPRINTF_PUTCHAR(' ');
 1428                 }
 1429         }
 1430 
 1431 done:
 1432         if ((oflags == TOBUFONLY) && (vp != NULL))
 1433                 *(char **)vp = sbuf;
 1434         (*v_flush)();
 1435 overflow:
 1436         return (ret);
 1437         /* NOTREACHED */
 1438 }

Cache object: bfcdcfa4b47020fabef89b1275f2485c


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