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 /*      $OpenBSD: subr_prf.c,v 1.106 2022/08/14 01:58:28 jsg Exp $      */
    2 /*      $NetBSD: subr_prf.c,v 1.45 1997/10/24 18:14:25 chuck Exp $      */
    3 
    4 /*-
    5  * Copyright (c) 1986, 1988, 1991, 1993
    6  *      The Regents of the University of California.  All rights reserved.
    7  * (c) UNIX System Laboratories, Inc.
    8  * All or some portions of this file are derived from material licensed
    9  * to the University of California by American Telephone and Telegraph
   10  * Co. or Unix System Laboratories, Inc. and are reproduced herein with
   11  * the permission of UNIX System Laboratories, Inc.
   12  *
   13  * Redistribution and use in source and binary forms, with or without
   14  * modification, are permitted provided that the following conditions
   15  * are met:
   16  * 1. Redistributions of source code must retain the above copyright
   17  *    notice, this list of conditions and the following disclaimer.
   18  * 2. Redistributions in binary form must reproduce the above copyright
   19  *    notice, this list of conditions and the following disclaimer in the
   20  *    documentation and/or other materials provided with the distribution.
   21  * 3. Neither the name of the University nor the names of its contributors
   22  *    may be used to endorse or promote products derived from this software
   23  *    without specific prior written permission.
   24  *
   25  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   26  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   27  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   28  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   29  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   30  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   31  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   32  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   33  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   34  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   35  * SUCH DAMAGE.
   36  *
   37  *      @(#)subr_prf.c  8.3 (Berkeley) 1/21/94
   38  */
   39 
   40 #include <sys/param.h>
   41 #include <sys/systm.h>
   42 #include <sys/reboot.h>
   43 #include <sys/msgbuf.h>
   44 #include <sys/proc.h>
   45 #include <sys/tty.h>
   46 #include <sys/tprintf.h>
   47 #include <sys/syslog.h>
   48 #include <sys/pool.h>
   49 #include <sys/mutex.h>
   50 
   51 #include <dev/cons.h>
   52 
   53 /*
   54  * note that stdarg.h and the ansi style va_start macro is used for both
   55  * ansi and traditional c compilers.
   56  */
   57 #include <sys/stdarg.h>
   58 
   59 #ifdef DDB
   60 #include <ddb/db_output.h>      /* db_printf, db_putchar prototypes */
   61 #include <ddb/db_var.h>         /* db_log, db_radix */
   62 #endif
   63 
   64 
   65 /*
   66  * defines
   67  */
   68 
   69 /* flags for kprintf */
   70 #define TOCONS          0x01    /* to the console */
   71 #define TOTTY           0x02    /* to the process' tty */
   72 #define TOLOG           0x04    /* to the kernel message buffer */
   73 #define TOBUFONLY       0x08    /* to the buffer (only) [for snprintf] */
   74 #define TODDB           0x10    /* to ddb console */
   75 #define TOCOUNT         0x20    /* act like [v]snprintf */
   76 
   77 /* max size buffer kprintf needs to print quad_t [size in base 8 + \0] */
   78 #define KPRINTF_BUFSIZE         (sizeof(quad_t) * NBBY / 3 + 2)
   79 
   80 
   81 /*
   82  * local prototypes
   83  */
   84 
   85 int      kprintf(const char *, int, void *, char *, va_list);
   86 void     kputchar(int, int, struct tty *);
   87 
   88 struct mutex kprintf_mutex =
   89     MUTEX_INITIALIZER_FLAGS(IPL_HIGH, "kprintf", MTX_NOWITNESS);
   90 
   91 /*
   92  * globals
   93  */
   94 
   95 extern  int log_open;   /* subr_log: is /dev/klog open? */
   96 const   char *panicstr; /* arg to first call to panic (used as a flag
   97                            to indicate that panic has already been called). */
   98 #ifdef DDB
   99 /*
  100  * Enter ddb on panic.
  101  */
  102 int     db_panic = 1;
  103 
  104 /*
  105  * db_console controls if we can be able to enter ddb by a special key
  106  * combination (machine dependent).
  107  * If DDB_SAFE_CONSOLE is defined in the kernel configuration it allows
  108  * to break into console during boot. It's _really_ useful when debugging
  109  * some things in the kernel that can cause init(8) to crash.
  110  */
  111 #ifdef DDB_SAFE_CONSOLE
  112 int     db_console = 1;
  113 #else
  114 int     db_console = 0;
  115 #endif
  116 #endif
  117 
  118 /*
  119  * panic on spl assertion failure?
  120  */
  121 #ifdef SPLASSERT_WATCH
  122 int splassert_ctl = 3;
  123 #else
  124 int splassert_ctl = 1;
  125 #endif
  126 
  127 /*
  128  * v_putc: routine to putc on virtual console
  129  *
  130  * the v_putc pointer can be used to redirect the console cnputc elsewhere
  131  * [e.g. to a "virtual console"].
  132  */
  133 
  134 void (*v_putc)(int) = cnputc;   /* start with cnputc (normal cons) */
  135 
  136 /*
  137  * Silence kernel printf when masquerading as a bootloader.
  138  */
  139 #ifdef BOOT_QUIET
  140 int printf_flags = TOLOG;
  141 #else
  142 int printf_flags = TOCONS | TOLOG;
  143 #endif
  144 
  145 /*
  146  * functions
  147  */
  148 
  149 /*
  150  *      Partial support (the failure case) of the assertion facility
  151  *      commonly found in userland.
  152  */
  153 void
  154 __assert(const char *t, const char *f, int l, const char *e)
  155 {
  156 
  157         panic(__KASSERTSTR, t, e, f, l);
  158 }
  159 
  160 /*
  161  * tablefull: warn that a system table is full
  162  */
  163 
  164 void
  165 tablefull(const char *tab)
  166 {
  167         log(LOG_ERR, "%s: table is full\n", tab);
  168 }
  169 
  170 /*
  171  * If we have panicked, prefer db_printf() and db_vprintf() where
  172  * available.
  173  */
  174 #ifdef DDB
  175 #define panic_printf(...)       db_printf(__VA_ARGS__)
  176 #define panic_vprintf(...)      db_vprintf(__VA_ARGS__)
  177 #else
  178 #define panic_printf(...)       printf(__VA_ARGS__)
  179 #define panic_vprintf(...)      vprintf(__VA_ARGS__)
  180 #endif
  181 
  182 /*
  183  * panic: handle an unresolvable fatal error
  184  *
  185  * prints "panic: <message>" and reboots.   if called twice (i.e. recursive
  186  * call) we avoid trying to sync the disk and just reboot (to avoid
  187  * recursive panics).
  188  */
  189 
  190 void
  191 panic(const char *fmt, ...)
  192 {
  193         struct cpu_info *ci = curcpu();
  194         int bootopt;
  195         va_list ap;
  196 
  197         bootopt = RB_AUTOBOOT | RB_DUMP;
  198         if (atomic_cas_ptr(&panicstr, NULL, ci->ci_panicbuf) != NULL)
  199                 bootopt |= RB_NOSYNC;
  200 
  201         /* do not trigger assertions, we know that we are inconsistent */
  202         splassert_ctl = 0;
  203 
  204 #ifdef BOOT_QUIET
  205         printf_flags |= TOCONS; /* make sure we see kernel printf output */
  206 #endif
  207 
  208         /*
  209          * All panic messages are printed, but only the first panic on a
  210          * given CPU is written to its panicbuf.
  211          */
  212         if (ci->ci_panicbuf[0] == '\0') {
  213                 va_start(ap, fmt);
  214                 vsnprintf(ci->ci_panicbuf, sizeof(ci->ci_panicbuf), fmt, ap);
  215                 va_end(ap);
  216                 panic_printf("panic: %s\n", ci->ci_panicbuf);
  217         } else {
  218                 panic_printf("panic: ");
  219                 va_start(ap, fmt);
  220                 panic_vprintf(fmt, ap);
  221                 va_end(ap);
  222                 panic_printf("\n");
  223         }
  224 
  225 #ifdef DDB
  226         if (db_panic)
  227                 db_enter();
  228         else
  229                 db_stack_dump();
  230 #endif
  231         reboot(bootopt);
  232         /* NOTREACHED */
  233 }
  234 
  235 /*
  236  * We print only the function name. The file name is usually very long and
  237  * would eat tons of space in the kernel.
  238  */
  239 void
  240 splassert_fail(int wantipl, int haveipl, const char *func)
  241 {
  242         if (panicstr || db_active)
  243                 return;
  244 
  245         printf("splassert: %s: want %d have %d\n", func, wantipl, haveipl);
  246         switch (splassert_ctl) {
  247         case 1:
  248                 break;
  249         case 2:
  250 #ifdef DDB
  251                 db_stack_dump();
  252 #endif
  253                 break;
  254         case 3:
  255 #ifdef DDB
  256                 db_stack_dump();
  257                 db_enter();
  258 #endif
  259                 break;
  260         default:
  261                 panic("spl assertion failure in %s", func);
  262         }
  263 }
  264 
  265 /*
  266  * kernel logging functions: log, logpri, addlog
  267  */
  268 
  269 /*
  270  * log: write to the log buffer
  271  *
  272  * => will not sleep [so safe to call from interrupt]
  273  * => will log to console if /dev/klog isn't open
  274  */
  275 
  276 void
  277 log(int level, const char *fmt, ...)
  278 {
  279         int s;
  280         va_list ap;
  281 
  282         s = splhigh();
  283         logpri(level);          /* log the level first */
  284         va_start(ap, fmt);
  285         kprintf(fmt, TOLOG, NULL, NULL, ap);
  286         va_end(ap);
  287         splx(s);
  288         if (!log_open) {
  289                 va_start(ap, fmt);
  290                 mtx_enter(&kprintf_mutex);
  291                 kprintf(fmt, TOCONS, NULL, NULL, ap);
  292                 mtx_leave(&kprintf_mutex);
  293                 va_end(ap);
  294         }
  295         logwakeup();            /* wake up anyone waiting for log msgs */
  296 }
  297 
  298 /*
  299  * logpri: log the priority level to the klog
  300  */
  301 
  302 void
  303 logpri(int level)
  304 {
  305         char *p;
  306         char snbuf[KPRINTF_BUFSIZE];
  307 
  308         kputchar('<', TOLOG, NULL);
  309         snprintf(snbuf, sizeof snbuf, "%d", level);
  310         for (p = snbuf ; *p ; p++)
  311                 kputchar(*p, TOLOG, NULL);
  312         kputchar('>', TOLOG, NULL);
  313 }
  314 
  315 /*
  316  * addlog: add info to previous log message
  317  */
  318 
  319 int
  320 addlog(const char *fmt, ...)
  321 {
  322         int s;
  323         va_list ap;
  324 
  325         s = splhigh();
  326         va_start(ap, fmt);
  327         kprintf(fmt, TOLOG, NULL, NULL, ap);
  328         va_end(ap);
  329         splx(s);
  330         if (!log_open) {
  331                 va_start(ap, fmt);
  332                 mtx_enter(&kprintf_mutex);
  333                 kprintf(fmt, TOCONS, NULL, NULL, ap);
  334                 mtx_leave(&kprintf_mutex);
  335                 va_end(ap);
  336         }
  337         logwakeup();
  338         return(0);
  339 }
  340 
  341 
  342 /*
  343  * kputchar: print a single character on console or user terminal.
  344  *
  345  * => if console, then the last MSGBUFS chars are saved in msgbuf
  346  *      for inspection later (e.g. dmesg/syslog)
  347  */
  348 void
  349 kputchar(int c, int flags, struct tty *tp)
  350 {
  351         extern int msgbufmapped;
  352 
  353         if (panicstr)
  354                 constty = NULL;
  355 
  356         if ((flags & TOCONS) && tp == NULL && constty != NULL && !db_active) {
  357                 tp = constty;
  358                 flags |= TOTTY;
  359         }
  360         if ((flags & TOTTY) && tp && tputchar(c, tp) < 0 &&
  361             (flags & TOCONS) && tp == constty)
  362                 constty = NULL;
  363         if ((flags & TOLOG) &&
  364             c != '\0' && c != '\r' && c != 0177 && msgbufmapped)
  365                 msgbuf_putchar(msgbufp, c);
  366         if ((flags & TOCONS) && (constty == NULL || db_active) && c != '\0')
  367                 (*v_putc)(c);
  368 #ifdef DDB
  369         if (flags & TODDB)
  370                 db_putchar(c);
  371 #endif
  372 }
  373 
  374 
  375 /*
  376  * uprintf: print to the controlling tty of the current process
  377  *
  378  * => we may block if the tty queue is full
  379  * => no message is printed if the queue doesn't clear in a reasonable
  380  *      time
  381  */
  382 
  383 void
  384 uprintf(const char *fmt, ...)
  385 {
  386         struct process *pr = curproc->p_p;
  387         va_list ap;
  388 
  389         if (pr->ps_flags & PS_CONTROLT && pr->ps_session->s_ttyvp) {
  390                 va_start(ap, fmt);
  391                 kprintf(fmt, TOTTY, pr->ps_session->s_ttyp, NULL, ap);
  392                 va_end(ap);
  393         }
  394 }
  395 
  396 #if defined(NFSSERVER) || defined(NFSCLIENT)
  397 
  398 /*
  399  * tprintf functions: used to send messages to a specific process
  400  *
  401  * usage:
  402  *   get a tpr_t handle on a process "p" by using "tprintf_open(p)"
  403  *   use the handle when calling "tprintf"
  404  *   when done, do a "tprintf_close" to drop the handle
  405  */
  406 
  407 /*
  408  * tprintf_open: get a tprintf handle on a process "p"
  409  * XXX change s/proc/process
  410  *
  411  * => returns NULL if process can't be printed to
  412  */
  413 
  414 tpr_t
  415 tprintf_open(struct proc *p)
  416 {
  417         struct process *pr = p->p_p;
  418 
  419         if (pr->ps_flags & PS_CONTROLT && pr->ps_session->s_ttyvp) {
  420                 SESSHOLD(pr->ps_session);
  421                 return ((tpr_t)pr->ps_session);
  422         }
  423         return ((tpr_t) NULL);
  424 }
  425 
  426 /*
  427  * tprintf_close: dispose of a tprintf handle obtained with tprintf_open
  428  */
  429 
  430 void
  431 tprintf_close(tpr_t sess)
  432 {
  433 
  434         if (sess)
  435                 SESSRELE((struct session *) sess);
  436 }
  437 
  438 /*
  439  * tprintf: given tprintf handle to a process [obtained with tprintf_open],
  440  * send a message to the controlling tty for that process.
  441  *
  442  * => also sends message to /dev/klog
  443  */
  444 void
  445 tprintf(tpr_t tpr, const char *fmt, ...)
  446 {
  447         struct session *sess = (struct session *)tpr;
  448         struct tty *tp = NULL;
  449         int flags = TOLOG;
  450         va_list ap;
  451 
  452         logpri(LOG_INFO);
  453         if (sess && sess->s_ttyvp && ttycheckoutq(sess->s_ttyp, 0)) {
  454                 flags |= TOTTY;
  455                 tp = sess->s_ttyp;
  456         }
  457         va_start(ap, fmt);
  458         kprintf(fmt, flags, tp, NULL, ap);
  459         va_end(ap);
  460         logwakeup();
  461 }
  462 
  463 #endif  /* NFSSERVER || NFSCLIENT */
  464 
  465 
  466 /*
  467  * ttyprintf: send a message to a specific tty
  468  *
  469  * => should be used only by tty driver or anything that knows the
  470  *      underlying tty will not be revoked(2)'d away.  [otherwise,
  471  *      use tprintf]
  472  */
  473 void
  474 ttyprintf(struct tty *tp, const char *fmt, ...)
  475 {
  476         va_list ap;
  477 
  478         va_start(ap, fmt);
  479         kprintf(fmt, TOTTY, tp, NULL, ap);
  480         va_end(ap);
  481 }
  482 
  483 #ifdef DDB
  484 
  485 /*
  486  * db_printf: printf for DDB (via db_putchar)
  487  */
  488 
  489 int
  490 db_printf(const char *fmt, ...)
  491 {
  492         va_list ap;
  493         int retval;
  494 
  495         va_start(ap, fmt);
  496         retval = db_vprintf(fmt, ap);
  497         va_end(ap);
  498         return(retval);
  499 }
  500 
  501 int
  502 db_vprintf(const char *fmt, va_list ap)
  503 {
  504         int flags;
  505 
  506         flags = TODDB;
  507         if (db_log)
  508                 flags |= TOLOG;
  509         return (kprintf(fmt, flags, NULL, NULL, ap));
  510 }
  511 #endif /* DDB */
  512 
  513 
  514 /*
  515  * normal kernel printf functions: printf, vprintf, snprintf
  516  */
  517 
  518 /*
  519  * printf: print a message to the console and the log
  520  */
  521 int
  522 printf(const char *fmt, ...)
  523 {
  524         va_list ap;
  525         int retval;
  526 
  527         va_start(ap, fmt);
  528         mtx_enter(&kprintf_mutex);
  529         retval = kprintf(fmt, printf_flags, NULL, NULL, ap);
  530         mtx_leave(&kprintf_mutex);
  531         va_end(ap);
  532         if (!panicstr)
  533                 logwakeup();
  534 
  535 
  536         return(retval);
  537 }
  538 
  539 /*
  540  * vprintf: print a message to the console and the log [already have a
  541  *      va_list]
  542  */
  543 
  544 int
  545 vprintf(const char *fmt, va_list ap)
  546 {
  547         int retval;
  548 
  549         mtx_enter(&kprintf_mutex);
  550         retval = kprintf(fmt, TOCONS | TOLOG, NULL, NULL, ap);
  551         mtx_leave(&kprintf_mutex);
  552         if (!panicstr)
  553                 logwakeup();
  554 
  555 
  556         return (retval);
  557 }
  558 
  559 /*
  560  * snprintf: print a message to a buffer
  561  */
  562 int
  563 snprintf(char *buf, size_t size, const char *fmt, ...)
  564 {
  565         int retval;
  566         va_list ap;
  567         char *p;
  568 
  569         p = buf;
  570         if (size > 0)
  571                 p += size - 1;
  572         va_start(ap, fmt);
  573         retval = kprintf(fmt, TOBUFONLY | TOCOUNT, &p, buf, ap);
  574         va_end(ap);
  575         if (size > 0)
  576                 *p = '\0';      /* null terminate */
  577         return(retval);
  578 }
  579 
  580 /*
  581  * vsnprintf: print a message to a buffer [already have va_alist]
  582  */
  583 int
  584 vsnprintf(char *buf, size_t size, const char *fmt, va_list ap)
  585 {
  586         int retval;
  587         char *p;
  588 
  589         p = buf + size - 1;
  590         if (size < 1)
  591                 p = buf;
  592         retval = kprintf(fmt, TOBUFONLY | TOCOUNT, &p, buf, ap);
  593         if (size > 0)
  594                 *(p) = 0;       /* null terminate */
  595         return(retval);
  596 }
  597 
  598 /*
  599  * kprintf: scaled down version of printf(3).
  600  *
  601  * this version based on vfprintf() from libc which was derived from
  602  * software contributed to Berkeley by Chris Torek.
  603  *
  604  * The additional format %b is supported to decode error registers.
  605  * Its usage is:
  606  *
  607  *      printf("reg=%b\n", regval, "<base><arg>*");
  608  *
  609  * where <base> is the output base expressed as a control character, e.g.
  610  * \10 gives octal; \20 gives hex.  Each arg is a sequence of characters,
  611  * the first of which gives the bit number to be inspected (origin 1), and
  612  * the next characters (up to a control character, i.e. a character <= 32),
  613  * give the name of the register.  Thus:
  614  *
  615  *      kprintf("reg=%b\n", 3, "\1\2BITTWO\1BITONE\n");
  616  *
  617  * would produce output:
  618  *
  619  *      reg=3<BITTWO,BITONE>
  620  *
  621  * To support larger integers (> 32 bits), %b formatting will also accept
  622  * control characters in the region 0x80 - 0xff.  0x80 refers to bit 0,
  623  * 0x81 refers to bit 1, and so on.  The equivalent string to the above is:
  624  *
  625  *      kprintf("reg=%b\n", 3, "\1\201BITTWO\200BITONE\n");
  626  *
  627  * and would produce the same output.
  628  *
  629  * Like the rest of printf, %b can be prefixed to handle various size
  630  * modifiers, eg. %b is for "int", %lb is for "long", and %llb supports
  631  * "long long".
  632  *
  633  * This code is large and complicated...
  634  */
  635 
  636 /*
  637  * macros for converting digits to letters and vice versa
  638  */
  639 #define to_digit(c)     ((c) - '')
  640 #define is_digit(c)     ((unsigned)to_digit(c) <= 9)
  641 #define to_char(n)      ((n) + '')
  642 
  643 /*
  644  * flags used during conversion.
  645  */
  646 #define ALT             0x001           /* alternate form */
  647 #define HEXPREFIX       0x002           /* add 0x or 0X prefix */
  648 #define LADJUST         0x004           /* left adjustment */
  649 #define LONGDBL         0x008           /* long double; unimplemented */
  650 #define LONGINT         0x010           /* long integer */
  651 #define QUADINT         0x020           /* quad integer */
  652 #define SHORTINT        0x040           /* short integer */
  653 #define ZEROPAD         0x080           /* zero (as opposed to blank) pad */
  654 #define FPT             0x100           /* Floating point number */
  655 #define SIZEINT         0x200           /* (signed) size_t */
  656 
  657         /*
  658          * To extend shorts properly, we need both signed and unsigned
  659          * argument extraction methods.
  660          */
  661 #define SARG() \
  662         (flags&QUADINT ? va_arg(ap, quad_t) : \
  663             flags&LONGINT ? va_arg(ap, long) : \
  664             flags&SIZEINT ? va_arg(ap, ssize_t) : \
  665             flags&SHORTINT ? (long)(short)va_arg(ap, int) : \
  666             (long)va_arg(ap, int))
  667 #define UARG() \
  668         (flags&QUADINT ? va_arg(ap, u_quad_t) : \
  669             flags&LONGINT ? va_arg(ap, u_long) : \
  670             flags&SIZEINT ? va_arg(ap, size_t) : \
  671             flags&SHORTINT ? (u_long)(u_short)va_arg(ap, int) : \
  672             (u_long)va_arg(ap, u_int))
  673 
  674 #define KPRINTF_PUTCHAR(C) do {                                 \
  675         int chr = (C);                                          \
  676         ret += 1;                                               \
  677         if (oflags & TOBUFONLY) {                               \
  678                 if ((vp != NULL) && (sbuf == tailp)) {          \
  679                         if (!(oflags & TOCOUNT))                \
  680                                 goto overflow;                  \
  681                 } else                                          \
  682                         *sbuf++ = chr;                          \
  683         } else {                                                \
  684                 kputchar(chr, oflags, (struct tty *)vp);        \
  685         }                                                       \
  686 } while(0)
  687 
  688 int
  689 kprintf(const char *fmt0, int oflags, void *vp, char *sbuf, va_list ap)
  690 {
  691         char *fmt;              /* format string */
  692         int ch;                 /* character from fmt */
  693         int n;                  /* handy integer (short term usage) */
  694         char *cp = NULL;        /* handy char pointer (short term usage) */
  695         int flags;              /* flags as above */
  696         int ret;                /* return value accumulator */
  697         int width;              /* width from format (%8d), or 0 */
  698         int prec;               /* precision from format (%.3d), or -1 */
  699         char sign;              /* sign prefix (' ', '+', '-', or \0) */
  700 
  701         u_quad_t _uquad;        /* integer arguments %[diouxX] */
  702         enum { OCT, DEC, HEX } base;/* base for [diouxX] conversion */
  703         int dprec;              /* a copy of prec if [diouxX], 0 otherwise */
  704         int realsz;             /* field size expanded by dprec */
  705         int size = 0;           /* size of converted field or string */
  706         char *xdigs = NULL;     /* digits for [xX] conversion */
  707         char buf[KPRINTF_BUFSIZE]; /* space for %c, %[diouxX] */
  708         char *tailp = NULL;     /* tail pointer for snprintf */
  709 
  710         if (oflags & TOCONS)
  711                 MUTEX_ASSERT_LOCKED(&kprintf_mutex);
  712 
  713         if ((oflags & TOBUFONLY) && (vp != NULL))
  714                 tailp = *(char **)vp;
  715 
  716         fmt = (char *)fmt0;
  717         ret = 0;
  718 
  719         /*
  720          * Scan the format for conversions (`%' character).
  721          */
  722         for (;;) {
  723                 while (*fmt != '%' && *fmt) {
  724                         KPRINTF_PUTCHAR(*fmt++);
  725                 }
  726                 if (*fmt == 0)
  727                         goto done;
  728 
  729                 fmt++;          /* skip over '%' */
  730 
  731                 flags = 0;
  732                 dprec = 0;
  733                 width = 0;
  734                 prec = -1;
  735                 sign = '\0';
  736 
  737 rflag:          ch = *fmt++;
  738 reswitch:       switch (ch) {
  739                 /* XXX: non-standard '%b' format */
  740                 case 'b': {
  741                         char *b, *z;
  742                         int tmp;
  743                         _uquad = UARG();
  744                         b = va_arg(ap, char *);
  745                         if (*b == 8)
  746                                 snprintf(buf, sizeof buf, "%llo", _uquad);
  747                         else if (*b == 10)
  748                                 snprintf(buf, sizeof buf, "%lld", _uquad);
  749                         else if (*b == 16)
  750                                 snprintf(buf, sizeof buf, "%llx", _uquad);
  751                         else
  752                                 break;
  753                         b++;
  754 
  755                         z = buf;
  756                         while (*z) {
  757                                 KPRINTF_PUTCHAR(*z++);
  758                         }
  759 
  760                         if (_uquad) {
  761                                 tmp = 0;
  762                                 while ((n = *b++) != 0) {
  763                                         if (n & 0x80)
  764                                                 n &= 0x7f;
  765                                         else if (n <= ' ')
  766                                                 n = n - 1;
  767                                         if (_uquad & (1LL << n)) {
  768                                                 KPRINTF_PUTCHAR(tmp ? ',':'<');
  769                                                 while (*b > ' ' &&
  770                                                     (*b & 0x80) == 0) {
  771                                                         KPRINTF_PUTCHAR(*b);
  772                                                         b++;
  773                                                 }
  774                                                 tmp = 1;
  775                                         } else {
  776                                                 while (*b > ' ' &&
  777                                                     (*b & 0x80) == 0)
  778                                                         b++;
  779                                         }
  780                                 }
  781                                 if (tmp) {
  782                                         KPRINTF_PUTCHAR('>');
  783                                 }
  784                         }
  785                         continue;       /* no output */
  786                 }
  787 
  788                 case ' ':
  789                         /*
  790                          * ``If the space and + flags both appear, the space
  791                          * flag will be ignored.''
  792                          *      -- ANSI X3J11
  793                          */
  794                         if (!sign)
  795                                 sign = ' ';
  796                         goto rflag;
  797                 case '#':
  798                         flags |= ALT;
  799                         goto rflag;
  800                 case '*':
  801                         /*
  802                          * ``A negative field width argument is taken as a
  803                          * - flag followed by a positive field width.''
  804                          *      -- ANSI X3J11
  805                          * They don't exclude field widths read from args.
  806                          */
  807                         if ((width = va_arg(ap, int)) >= 0)
  808                                 goto rflag;
  809                         width = -width;
  810                         /* FALLTHROUGH */
  811                 case '-':
  812                         flags |= LADJUST;
  813                         goto rflag;
  814                 case '+':
  815                         sign = '+';
  816                         goto rflag;
  817                 case '.':
  818                         if ((ch = *fmt++) == '*') {
  819                                 n = va_arg(ap, int);
  820                                 prec = n < 0 ? -1 : n;
  821                                 goto rflag;
  822                         }
  823                         n = 0;
  824                         while (is_digit(ch)) {
  825                                 n = 10 * n + to_digit(ch);
  826                                 ch = *fmt++;
  827                         }
  828                         prec = n < 0 ? -1 : n;
  829                         goto reswitch;
  830                 case '':
  831                         /*
  832                          * ``Note that 0 is taken as a flag, not as the
  833                          * beginning of a field width.''
  834                          *      -- ANSI X3J11
  835                          */
  836                         flags |= ZEROPAD;
  837                         goto rflag;
  838                 case '1': case '2': case '3': case '4':
  839                 case '5': case '6': case '7': case '8': case '9':
  840                         n = 0;
  841                         do {
  842                                 n = 10 * n + to_digit(ch);
  843                                 ch = *fmt++;
  844                         } while (is_digit(ch));
  845                         width = n;
  846                         goto reswitch;
  847                 case 'h':
  848                         flags |= SHORTINT;
  849                         goto rflag;
  850                 case 'l':
  851                         if (*fmt == 'l') {
  852                                 fmt++;
  853                                 flags |= QUADINT;
  854                         } else {
  855                                 flags |= LONGINT;
  856                         }
  857                         goto rflag;
  858                 case 'q':
  859                         flags |= QUADINT;
  860                         goto rflag;
  861                 case 'z':
  862                         flags |= SIZEINT;
  863                         goto rflag;
  864                 case 'c':
  865                         *(cp = buf) = va_arg(ap, int);
  866                         size = 1;
  867                         sign = '\0';
  868                         break;
  869                 case 't':
  870                         /* ptrdiff_t */
  871                         /* FALLTHROUGH */
  872                 case 'D':
  873                         flags |= LONGINT;
  874                         /*FALLTHROUGH*/
  875                 case 'd':
  876                 case 'i':
  877                         _uquad = SARG();
  878                         if ((quad_t)_uquad < 0) {
  879                                 _uquad = -_uquad;
  880                                 sign = '-';
  881                         }
  882                         base = DEC;
  883                         goto number;
  884                 case 'n':
  885                         panic("no %%n support");
  886                         break;
  887                 case 'O':
  888                         flags |= LONGINT;
  889                         /*FALLTHROUGH*/
  890                 case 'o':
  891                         _uquad = UARG();
  892                         base = OCT;
  893                         goto nosign;
  894                 case 'p':
  895                         /*
  896                          * ``The argument shall be a pointer to void.  The
  897                          * value of the pointer is converted to a sequence
  898                          * of printable characters, in an implementation-
  899                          * defined manner.''
  900                          *      -- ANSI X3J11
  901                          */
  902                         _uquad = (u_long)va_arg(ap, void *);
  903                         base = HEX;
  904                         xdigs = "0123456789abcdef";
  905                         flags |= HEXPREFIX;
  906                         ch = 'x';
  907                         goto nosign;
  908                 case 's':
  909                         if ((cp = va_arg(ap, char *)) == NULL)
  910                                 cp = "(null)";
  911                         if (prec >= 0) {
  912                                 /*
  913                                  * can't use strlen; can only look for the
  914                                  * NUL in the first `prec' characters, and
  915                                  * strlen() will go further.
  916                                  */
  917                                 char *p = memchr(cp, 0, prec);
  918 
  919                                 if (p != NULL) {
  920                                         size = p - cp;
  921                                         if (size > prec)
  922                                                 size = prec;
  923                                 } else
  924                                         size = prec;
  925                         } else
  926                                 size = strlen(cp);
  927                         sign = '\0';
  928                         break;
  929                 case 'U':
  930                         flags |= LONGINT;
  931                         /*FALLTHROUGH*/
  932                 case 'u':
  933                         _uquad = UARG();
  934                         base = DEC;
  935                         goto nosign;
  936                 case 'X':
  937                         xdigs = "0123456789ABCDEF";
  938                         goto hex;
  939                 case 'x':
  940                         xdigs = "0123456789abcdef";
  941 hex:                    _uquad = UARG();
  942                         base = HEX;
  943                         /* leading 0x/X only if non-zero */
  944                         if (flags & ALT && _uquad != 0)
  945                                 flags |= HEXPREFIX;
  946 
  947                         /* unsigned conversions */
  948 nosign:                 sign = '\0';
  949                         /*
  950                          * ``... diouXx conversions ... if a precision is
  951                          * specified, the 0 flag will be ignored.''
  952                          *      -- ANSI X3J11
  953                          */
  954 number:                 if ((dprec = prec) >= 0)
  955                                 flags &= ~ZEROPAD;
  956 
  957                         /*
  958                          * ``The result of converting a zero value with an
  959                          * explicit precision of zero is no characters.''
  960                          *      -- ANSI X3J11
  961                          */
  962                         cp = buf + KPRINTF_BUFSIZE;
  963                         if (_uquad != 0 || prec != 0) {
  964                                 /*
  965                                  * Unsigned mod is hard, and unsigned mod
  966                                  * by a constant is easier than that by
  967                                  * a variable; hence this switch.
  968                                  */
  969                                 switch (base) {
  970                                 case OCT:
  971                                         do {
  972                                                 *--cp = to_char(_uquad & 7);
  973                                                 _uquad >>= 3;
  974                                         } while (_uquad);
  975                                         /* handle octal leading 0 */
  976                                         if (flags & ALT && *cp != '')
  977                                                 *--cp = '';
  978                                         break;
  979 
  980                                 case DEC:
  981                                         /* many numbers are 1 digit */
  982                                         while (_uquad >= 10) {
  983                                                 *--cp = to_char(_uquad % 10);
  984                                                 _uquad /= 10;
  985                                         }
  986                                         *--cp = to_char(_uquad);
  987                                         break;
  988 
  989                                 case HEX:
  990                                         do {
  991                                                 *--cp = xdigs[_uquad & 15];
  992                                                 _uquad >>= 4;
  993                                         } while (_uquad);
  994                                         break;
  995 
  996                                 default:
  997                                         cp = "bug in kprintf: bad base";
  998                                         size = strlen(cp);
  999                                         goto skipsize;
 1000                                 }
 1001                         }
 1002                         size = buf + KPRINTF_BUFSIZE - cp;
 1003                 skipsize:
 1004                         break;
 1005                 default:        /* "%?" prints ?, unless ? is NUL */
 1006                         if (ch == '\0')
 1007                                 goto done;
 1008                         /* pretend it was %c with argument ch */
 1009                         cp = buf;
 1010                         *cp = ch;
 1011                         size = 1;
 1012                         sign = '\0';
 1013                         break;
 1014                 }
 1015 
 1016                 /*
 1017                  * All reasonable formats wind up here.  At this point, `cp'
 1018                  * points to a string which (if not flags&LADJUST) should be
 1019                  * padded out to `width' places.  If flags&ZEROPAD, it should
 1020                  * first be prefixed by any sign or other prefix; otherwise,
 1021                  * it should be blank padded before the prefix is emitted.
 1022                  * After any left-hand padding and prefixing, emit zeroes
 1023                  * required by a decimal [diouxX] precision, then print the
 1024                  * string proper, then emit zeroes required by any leftover
 1025                  * floating precision; finally, if LADJUST, pad with blanks.
 1026                  *
 1027                  * Compute actual size, so we know how much to pad.
 1028                  * size excludes decimal prec; realsz includes it.
 1029                  */
 1030                 realsz = dprec > size ? dprec : size;
 1031                 if (sign)
 1032                         realsz++;
 1033                 else if (flags & HEXPREFIX)
 1034                         realsz+= 2;
 1035 
 1036                 /* right-adjusting blank padding */
 1037                 if ((flags & (LADJUST|ZEROPAD)) == 0) {
 1038                         n = width - realsz;
 1039                         while (n-- > 0)
 1040                                 KPRINTF_PUTCHAR(' ');
 1041                 }
 1042 
 1043                 /* prefix */
 1044                 if (sign) {
 1045                         KPRINTF_PUTCHAR(sign);
 1046                 } else if (flags & HEXPREFIX) {
 1047                         KPRINTF_PUTCHAR('');
 1048                         KPRINTF_PUTCHAR(ch);
 1049                 }
 1050 
 1051                 /* right-adjusting zero padding */
 1052                 if ((flags & (LADJUST|ZEROPAD)) == ZEROPAD) {
 1053                         n = width - realsz;
 1054                         while (n-- > 0)
 1055                                 KPRINTF_PUTCHAR('');
 1056                 }
 1057 
 1058                 /* leading zeroes from decimal precision */
 1059                 n = dprec - size;
 1060                 while (n-- > 0)
 1061                         KPRINTF_PUTCHAR('');
 1062 
 1063                 /* the string or number proper */
 1064                 while (size--)
 1065                         KPRINTF_PUTCHAR(*cp++);
 1066                 /* left-adjusting padding (always blank) */
 1067                 if (flags & LADJUST) {
 1068                         n = width - realsz;
 1069                         while (n-- > 0)
 1070                                 KPRINTF_PUTCHAR(' ');
 1071                 }
 1072         }
 1073 
 1074 done:
 1075         if ((oflags & TOBUFONLY) && (vp != NULL))
 1076                 *(char **)vp = sbuf;
 1077 overflow:
 1078         return (ret);
 1079         /* NOTREACHED */
 1080 }
 1081 
 1082 #if __GNUC_PREREQ__(2,96)
 1083 /*
 1084  * XXX - these functions shouldn't be in the kernel, but gcc 3.X feels like
 1085  *       translating some printf calls to puts and since it doesn't seem
 1086  *       possible to just turn off parts of those optimizations (some of
 1087  *       them are really useful), we have to provide a dummy puts and putchar
 1088  *       that are wrappers around printf.
 1089  */
 1090 int     puts(const char *);
 1091 int     putchar(int c);
 1092 
 1093 int
 1094 puts(const char *str)
 1095 {
 1096         printf("%s\n", str);
 1097 
 1098         return (0);
 1099 }
 1100 
 1101 int
 1102 putchar(int c)
 1103 {
 1104         printf("%c", c);
 1105 
 1106         return (c);
 1107 }
 1108 
 1109 
 1110 #endif

Cache object: 02eb306ca648f77469aebbe411e0860b


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