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 /*-
    2  * Copyright (c) 1986, 1988, 1991, 1993
    3  *      The Regents of the University of California.  All rights reserved.
    4  * (c) UNIX System Laboratories, Inc.
    5  * All or some portions of this file are derived from material licensed
    6  * to the University of California by American Telephone and Telegraph
    7  * Co. or Unix System Laboratories, Inc. and are reproduced herein with
    8  * the permission of UNIX System Laboratories, Inc.
    9  *
   10  * Redistribution and use in source and binary forms, with or without
   11  * modification, are permitted provided that the following conditions
   12  * are met:
   13  * 1. Redistributions of source code must retain the above copyright
   14  *    notice, this list of conditions and the following disclaimer.
   15  * 2. Redistributions in binary form must reproduce the above copyright
   16  *    notice, this list of conditions and the following disclaimer in the
   17  *    documentation and/or other materials provided with the distribution.
   18  * 3. All advertising materials mentioning features or use of this software
   19  *    must display the following acknowledgement:
   20  *      This product includes software developed by the University of
   21  *      California, Berkeley and its contributors.
   22  * 4. Neither the name of the University nor the names of its contributors
   23  *    may be used to endorse or promote products derived from this software
   24  *    without specific prior written permission.
   25  *
   26  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   27  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   28  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   29  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   30  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   31  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   32  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   33  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   34  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   35  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   36  * SUCH DAMAGE.
   37  *
   38  *      @(#)subr_prf.c  8.3 (Berkeley) 1/21/94
   39  * $FreeBSD$
   40  */
   41 
   42 #include <sys/param.h>
   43 #include <sys/systm.h>
   44 #include <sys/kernel.h>
   45 #include <sys/msgbuf.h>
   46 #include <sys/malloc.h>
   47 #include <sys/proc.h>
   48 #include <sys/tty.h>
   49 #include <sys/tprintf.h>
   50 #include <sys/syslog.h>
   51 #include <machine/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 <machine/stdarg.h>
   58 
   59 #define TOCONS  0x01
   60 #define TOTTY   0x02
   61 #define TOLOG   0x04
   62 
   63 /* Max number conversion buffer length: a long in base 2, plus NUL byte. */
   64 #define MAXNBUF (sizeof(long) * NBBY + 1)
   65 
   66 struct putchar_arg {
   67         int     flags;
   68         struct  tty *tty;
   69 };
   70 
   71 struct snprintf_arg {
   72         char    *str;
   73         size_t  remain;
   74 };
   75 
   76 struct  tty *constty;                   /* pointer to console "window" tty */
   77 
   78 static void (*v_putc)(int) = cnputc;    /* routine to putc on virtual console */
   79 static void  logpri __P((int level));
   80 static void  msglogchar(int c, void *dummyarg);
   81 static void  putchar __P((int ch, void *arg));
   82 static char *ksprintn __P((char *nbuf, u_long num, int base, int *len));
   83 static void  snprintf_func __P((int ch, void *arg));
   84 
   85 static int consintr = 1;                /* Ok to handle console interrupts? */
   86 static int msgbufmapped;                /* Set when safe to use msgbuf */
   87 
   88 /*
   89  * Warn that a system table is full.
   90  */
   91 void
   92 tablefull(tab)
   93         const char *tab;
   94 {
   95 
   96         log(LOG_ERR, "%s: table is full\n", tab);
   97 }
   98 
   99 /*
  100  * Uprintf prints to the controlling terminal for the current process.
  101  * It may block if the tty queue is overfull.  No message is printed if
  102  * the queue does not clear in a reasonable time.
  103  */
  104 void
  105 uprintf(const char *fmt, ...)
  106 {
  107         struct proc *p = curproc;
  108         va_list ap;
  109         struct putchar_arg pca;
  110 
  111         if (p->p_flag & P_CONTROLT && p->p_session->s_ttyvp) {
  112                 va_start(ap, fmt);
  113                 pca.tty = p->p_session->s_ttyp;
  114                 pca.flags = TOTTY;
  115                 kvprintf(fmt, putchar, &pca, 10, ap);
  116                 va_end(ap);
  117         }
  118 }
  119 
  120 tpr_t
  121 tprintf_open(p)
  122         register struct proc *p;
  123 {
  124 
  125         if (p->p_flag & P_CONTROLT && p->p_session->s_ttyvp) {
  126                 SESSHOLD(p->p_session);
  127                 return ((tpr_t) p->p_session);
  128         }
  129         return ((tpr_t) NULL);
  130 }
  131 
  132 void
  133 tprintf_close(sess)
  134         tpr_t sess;
  135 {
  136 
  137         if (sess)
  138                 SESSRELE((struct session *) sess);
  139 }
  140 
  141 /*
  142  * tprintf prints on the controlling terminal associated
  143  * with the given session.
  144  */
  145 void
  146 tprintf(tpr_t tpr, const char *fmt, ...)
  147 {
  148         register struct session *sess = (struct session *)tpr;
  149         struct tty *tp = NULL;
  150         int flags = TOLOG;
  151         va_list ap;
  152         struct putchar_arg pca;
  153 
  154         logpri(LOG_INFO);
  155         if (sess && sess->s_ttyvp && ttycheckoutq(sess->s_ttyp, 0)) {
  156                 flags |= TOTTY;
  157                 tp = sess->s_ttyp;
  158         }
  159         va_start(ap, fmt);
  160         pca.tty = tp;
  161         pca.flags = flags;
  162         kvprintf(fmt, putchar, &pca, 10, ap);
  163         va_end(ap);
  164         logwakeup();
  165 }
  166 
  167 /*
  168  * Ttyprintf displays a message on a tty; it should be used only by
  169  * the tty driver, or anything that knows the underlying tty will not
  170  * be revoke(2)'d away.  Other callers should use tprintf.
  171  */
  172 void
  173 ttyprintf(struct tty *tp, const char *fmt, ...)
  174 {
  175         va_list ap;
  176         struct putchar_arg pca;
  177         va_start(ap, fmt);
  178         pca.tty = tp;
  179         pca.flags = TOTTY;
  180         kvprintf(fmt, putchar, &pca, 10, ap);
  181         va_end(ap);
  182 }
  183 
  184 extern  int log_open;
  185 
  186 /*
  187  * Log writes to the log buffer, and guarantees not to sleep (so can be
  188  * called by interrupt routines).  If there is no process reading the
  189  * log yet, it writes to the console also.
  190  */
  191 void
  192 log(int level, const char *fmt, ...)
  193 {
  194         register int s;
  195         va_list ap;
  196 
  197         s = splhigh();
  198         logpri(level);
  199         va_start(ap, fmt);
  200 
  201         kvprintf(fmt, msglogchar, NULL, 10, ap);
  202         va_end(ap);
  203 
  204         splx(s);
  205         if (!log_open) {
  206                 struct putchar_arg pca;
  207                 va_start(ap, fmt);
  208                 pca.tty = NULL;
  209                 pca.flags = TOCONS;
  210                 kvprintf(fmt, putchar, &pca, 10, ap);
  211                 va_end(ap);
  212         }
  213         logwakeup();
  214 }
  215 
  216 static void
  217 logpri(level)
  218         int level;
  219 {
  220         char nbuf[MAXNBUF];
  221         register char *p;
  222 
  223         msglogchar('<', NULL);
  224         for (p = ksprintn(nbuf, (u_long)level, 10, NULL); *p;)
  225                 msglogchar(*p--, NULL);
  226         msglogchar('>', NULL);
  227 }
  228 
  229 int
  230 addlog(const char *fmt, ...)
  231 {
  232         register int s;
  233         va_list ap;
  234         int retval;
  235 
  236         s = splhigh();
  237         va_start(ap, fmt);
  238         retval = kvprintf(fmt, msglogchar, NULL, 10, ap);
  239         splx(s);
  240         va_end(ap);
  241         if (!log_open) {
  242                 struct putchar_arg pca;
  243                 va_start(ap, fmt);
  244                 pca.tty = NULL;
  245                 pca.flags = TOCONS;
  246                 kvprintf(fmt, putchar, &pca, 10, ap);
  247                 va_end(ap);
  248         }
  249         logwakeup();
  250         return (retval);
  251 }
  252 
  253 int
  254 printf(const char *fmt, ...)
  255 {
  256         va_list ap;
  257         register int savintr;
  258         struct putchar_arg pca;
  259         int retval;
  260 
  261         savintr = consintr;             /* disable interrupts */
  262         consintr = 0;
  263         va_start(ap, fmt);
  264         pca.tty = NULL;
  265         pca.flags = TOCONS | TOLOG;
  266         retval = kvprintf(fmt, putchar, &pca, 10, ap);
  267         va_end(ap);
  268         if (!panicstr)
  269                 logwakeup();
  270         consintr = savintr;             /* reenable interrupts */
  271         return retval;
  272 }
  273 
  274 void
  275 vprintf(const char *fmt, va_list ap)
  276 {
  277         register int savintr;
  278         struct putchar_arg pca;
  279 
  280         savintr = consintr;             /* disable interrupts */
  281         consintr = 0;
  282         pca.tty = NULL;
  283         pca.flags = TOCONS | TOLOG;
  284         kvprintf(fmt, putchar, &pca, 10, ap);
  285         if (!panicstr)
  286                 logwakeup();
  287         consintr = savintr;             /* reenable interrupts */
  288 }
  289 
  290 /*
  291  * Print a character on console or users terminal.  If destination is
  292  * the console then the last bunch of characters are saved in msgbuf for
  293  * inspection later.
  294  */
  295 static void
  296 putchar(int c, void *arg)
  297 {
  298         struct putchar_arg *ap = (struct putchar_arg*) arg;
  299         int flags = ap->flags;
  300         struct tty *tp = ap->tty;
  301         if (panicstr)
  302                 constty = NULL;
  303         if ((flags & TOCONS) && tp == NULL && constty) {
  304                 tp = constty;
  305                 flags |= TOTTY;
  306         }
  307         if ((flags & TOTTY) && tp && tputchar(c, tp) < 0 &&
  308             (flags & TOCONS) && tp == constty)
  309                 constty = NULL;
  310         if ((flags & TOLOG))
  311                 msglogchar(c, NULL);
  312         if ((flags & TOCONS) && constty == NULL && c != '\0')
  313                 (*v_putc)(c);
  314 }
  315 
  316 /*
  317  * Scaled down version of sprintf(3).
  318  */
  319 int
  320 sprintf(char *buf, const char *cfmt, ...)
  321 {
  322         int retval;
  323         va_list ap;
  324 
  325         va_start(ap, cfmt);
  326         retval = kvprintf(cfmt, NULL, (void *)buf, 10, ap);
  327         buf[retval] = '\0';
  328         va_end(ap);
  329         return retval;
  330 }
  331 
  332 /*
  333  * Scaled down version of vsprintf(3).
  334  */
  335 int
  336 vsprintf(char *buf, const char *cfmt, va_list ap)
  337 {
  338         int retval;
  339 
  340         retval = kvprintf(cfmt, NULL, (void *)buf, 10, ap);
  341         buf[retval] = '\0';
  342         return retval;
  343 }
  344 
  345 /*
  346  * Scaled down version of snprintf(3).
  347  */
  348 int
  349 snprintf(char *str, size_t size, const char *format, ...)
  350 {
  351         int retval;
  352         va_list ap;
  353 
  354         va_start(ap, format);
  355         retval = vsnprintf(str, size, format, ap);
  356         va_end(ap);
  357         return(retval);
  358 }
  359 
  360 /*
  361  * Scaled down version of vsnprintf(3).
  362  */
  363 int
  364 vsnprintf(char *str, size_t size, const char *format, va_list ap)
  365 {
  366         struct snprintf_arg info;
  367         int retval;
  368 
  369         info.str = str;
  370         info.remain = size;
  371         retval = kvprintf(format, snprintf_func, &info, 10, ap);
  372         if (info.remain >= 1)
  373                 *info.str++ = '\0';
  374         return retval;
  375 }
  376 
  377 static void
  378 snprintf_func(int ch, void *arg)
  379 {
  380         struct snprintf_arg *const info = arg;
  381 
  382         if (info->remain >= 2) {
  383                 *info->str++ = ch;
  384                 info->remain--;
  385         }
  386 }
  387 
  388 /*
  389  * Put a NUL-terminated ASCII number (base <= 16) in a buffer in reverse
  390  * order; return an optional length and a pointer to the last character
  391  * written in the buffer (i.e., the first character of the string).
  392  * The buffer pointed to by `nbuf' must have length >= MAXNBUF.
  393  */
  394 static char *
  395 ksprintn(nbuf, ul, base, lenp)
  396         char *nbuf;
  397         register u_long ul;
  398         register int base, *lenp;
  399 {
  400         register char *p;
  401 
  402         p = nbuf;
  403         *p = '\0';
  404         do {
  405                 *++p = hex2ascii(ul % base);
  406         } while (ul /= base);
  407         if (lenp)
  408                 *lenp = p - nbuf;
  409         return (p);
  410 }
  411 
  412 /*
  413  * Scaled down version of printf(3).
  414  *
  415  * Two additional formats:
  416  *
  417  * The format %b is supported to decode error registers.
  418  * Its usage is:
  419  *
  420  *      printf("reg=%b\n", regval, "<base><arg>*");
  421  *
  422  * where <base> is the output base expressed as a control character, e.g.
  423  * \10 gives octal; \20 gives hex.  Each arg is a sequence of characters,
  424  * the first of which gives the bit number to be inspected (origin 1), and
  425  * the next characters (up to a control character, i.e. a character <= 32),
  426  * give the name of the register.  Thus:
  427  *
  428  *      kvprintf("reg=%b\n", 3, "\1\2BITTWO\1BITONE\n");
  429  *
  430  * would produce output:
  431  *
  432  *      reg=3<BITTWO,BITONE>
  433  *
  434  * XXX:  %D  -- Hexdump, takes pointer and separator string:
  435  *              ("%6D", ptr, ":")   -> XX:XX:XX:XX:XX:XX
  436  *              ("%*D", len, ptr, " " -> XX XX XX XX ...
  437  */
  438 int
  439 kvprintf(char const *fmt, void (*func)(int, void*), void *arg, int radix, va_list ap)
  440 {
  441 #define PCHAR(c) {int cc=(c); if (func) (*func)(cc,arg); else *d++ = cc; retval++; }
  442         char nbuf[MAXNBUF];
  443         char *p, *q, *d;
  444         u_char *up;
  445         int ch, n;
  446         u_long ul;
  447         int base, lflag, tmp, width, ladjust, sharpflag, neg, sign, dot;
  448         int dwidth;
  449         char padc;
  450         int retval = 0;
  451 
  452         if (!func)
  453                 d = (char *) arg;
  454         else
  455                 d = NULL;
  456 
  457         if (fmt == NULL)
  458                 fmt = "(fmt null)\n";
  459 
  460         if (radix < 2 || radix > 36)
  461                 radix = 10;
  462 
  463         for (;;) {
  464                 padc = ' ';
  465                 width = 0;
  466                 while ((ch = (u_char)*fmt++) != '%') {
  467                         if (ch == '\0') 
  468                                 return retval;
  469                         PCHAR(ch);
  470                 }
  471                 lflag = 0; ladjust = 0; sharpflag = 0; neg = 0;
  472                 sign = 0; dot = 0; dwidth = 0;
  473 reswitch:       switch (ch = (u_char)*fmt++) {
  474                 case '.':
  475                         dot = 1;
  476                         goto reswitch;
  477                 case '#':
  478                         sharpflag = 1;
  479                         goto reswitch;
  480                 case '+':
  481                         sign = 1;
  482                         goto reswitch;
  483                 case '-':
  484                         ladjust = 1;
  485                         goto reswitch;
  486                 case '%':
  487                         PCHAR(ch);
  488                         break;
  489                 case '*':
  490                         if (!dot) {
  491                                 width = va_arg(ap, int);
  492                                 if (width < 0) {
  493                                         ladjust = !ladjust;
  494                                         width = -width;
  495                                 }
  496                         } else {
  497                                 dwidth = va_arg(ap, int);
  498                         }
  499                         goto reswitch;
  500                 case '':
  501                         if (!dot) {
  502                                 padc = '';
  503                                 goto reswitch;
  504                         }
  505                 case '1': case '2': case '3': case '4':
  506                 case '5': case '6': case '7': case '8': case '9':
  507                                 for (n = 0;; ++fmt) {
  508                                         n = n * 10 + ch - '';
  509                                         ch = *fmt;
  510                                         if (ch < '' || ch > '9')
  511                                                 break;
  512                                 }
  513                         if (dot)
  514                                 dwidth = n;
  515                         else
  516                                 width = n;
  517                         goto reswitch;
  518                 case 'b':
  519                         ul = va_arg(ap, int);
  520                         p = va_arg(ap, char *);
  521                         for (q = ksprintn(nbuf, ul, *p++, NULL); *q;)
  522                                 PCHAR(*q--);
  523 
  524                         if (!ul)
  525                                 break;
  526 
  527                         for (tmp = 0; *p;) {
  528                                 n = *p++;
  529                                 if (ul & (1 << (n - 1))) {
  530                                         PCHAR(tmp ? ',' : '<');
  531                                         for (; (n = *p) > ' '; ++p)
  532                                                 PCHAR(n);
  533                                         tmp = 1;
  534                                 } else
  535                                         for (; *p > ' '; ++p)
  536                                                 continue;
  537                         }
  538                         if (tmp)
  539                                 PCHAR('>');
  540                         break;
  541                 case 'c':
  542                         PCHAR(va_arg(ap, int));
  543                         break;
  544                 case 'D':
  545                         up = va_arg(ap, u_char *);
  546                         p = va_arg(ap, char *);
  547                         if (!width)
  548                                 width = 16;
  549                         while(width--) {
  550                                 PCHAR(hex2ascii(*up >> 4));
  551                                 PCHAR(hex2ascii(*up & 0x0f));
  552                                 up++;
  553                                 if (width)
  554                                         for (q=p;*q;q++)
  555                                                 PCHAR(*q);
  556                         }
  557                         break;
  558                 case 'd':
  559                         ul = lflag ? va_arg(ap, long) : va_arg(ap, int);
  560                         sign = 1;
  561                         base = 10;
  562                         goto number;
  563                 case 'l':
  564                         lflag = 1;
  565                         goto reswitch;
  566                 case 'o':
  567                         ul = lflag ? va_arg(ap, u_long) : va_arg(ap, u_int);
  568                         base = 8;
  569                         goto nosign;
  570                 case 'p':
  571                         ul = (uintptr_t)va_arg(ap, void *);
  572                         base = 16;
  573                         sharpflag = (width == 0);
  574                         goto nosign;
  575                 case 'n':
  576                 case 'r':
  577                         ul = lflag ? va_arg(ap, u_long) :
  578                             sign ? (u_long)va_arg(ap, int) : va_arg(ap, u_int);
  579                         base = radix;
  580                         goto number;
  581                 case 's':
  582                         p = va_arg(ap, char *);
  583                         if (p == NULL)
  584                                 p = "(null)";
  585                         if (!dot)
  586                                 n = strlen (p);
  587                         else
  588                                 for (n = 0; n < dwidth && p[n]; n++)
  589                                         continue;
  590 
  591                         width -= n;
  592 
  593                         if (!ladjust && width > 0)
  594                                 while (width--)
  595                                         PCHAR(padc);
  596                         while (n--)
  597                                 PCHAR(*p++);
  598                         if (ladjust && width > 0)
  599                                 while (width--)
  600                                         PCHAR(padc);
  601                         break;
  602                 case 'u':
  603                         ul = lflag ? va_arg(ap, u_long) : va_arg(ap, u_int);
  604                         base = 10;
  605                         goto nosign;
  606                 case 'x':
  607                         ul = lflag ? va_arg(ap, u_long) : va_arg(ap, u_int);
  608                         base = 16;
  609                         goto nosign;
  610                 case 'z':
  611                         ul = lflag ? va_arg(ap, u_long) :
  612                             sign ? (u_long)va_arg(ap, int) : va_arg(ap, u_int);
  613                         base = 16;
  614                         goto number;
  615 nosign:                 sign = 0;
  616 number:                 if (sign && (long)ul < 0L) {
  617                                 neg = 1;
  618                                 ul = -(long)ul;
  619                         }
  620                         p = ksprintn(nbuf, ul, base, &tmp);
  621                         if (sharpflag && ul != 0) {
  622                                 if (base == 8)
  623                                         tmp++;
  624                                 else if (base == 16)
  625                                         tmp += 2;
  626                         }
  627                         if (neg)
  628                                 tmp++;
  629 
  630                         if (!ladjust && width && (width -= tmp) > 0)
  631                                 while (width--)
  632                                         PCHAR(padc);
  633                         if (neg)
  634                                 PCHAR('-');
  635                         if (sharpflag && ul != 0) {
  636                                 if (base == 8) {
  637                                         PCHAR('');
  638                                 } else if (base == 16) {
  639                                         PCHAR('');
  640                                         PCHAR('x');
  641                                 }
  642                         }
  643 
  644                         while (*p)
  645                                 PCHAR(*p--);
  646 
  647                         if (ladjust && width && (width -= tmp) > 0)
  648                                 while (width--)
  649                                         PCHAR(padc);
  650 
  651                         break;
  652                 default:
  653                         PCHAR('%');
  654                         if (lflag)
  655                                 PCHAR('l');
  656                         PCHAR(ch);
  657                         break;
  658                 }
  659         }
  660 #undef PCHAR
  661 }
  662 
  663 /*
  664  * Put character in log buffer.
  665  */
  666 static void
  667 msglogchar(int c, void *dummyarg)
  668 {
  669         struct msgbuf *mbp;
  670 
  671         if (c != '\0' && c != '\r' && c != 0177 && msgbufmapped) {
  672                 mbp = msgbufp;
  673                 mbp->msg_ptr[mbp->msg_bufx++] = c;
  674                 if (mbp->msg_bufx >= mbp->msg_size)
  675                         mbp->msg_bufx = 0;
  676                 /* If the buffer is full, keep the most recent data. */
  677                 if (mbp->msg_bufr == mbp->msg_bufx) {
  678                         if (++mbp->msg_bufr >= mbp->msg_size)
  679                                 mbp->msg_bufr = 0;
  680                 }
  681         }
  682 }
  683 
  684 void
  685 msgbufinit(void *ptr, size_t size)
  686 {
  687         char *cp;
  688 
  689         cp = (char *)ptr;
  690         msgbufp = (struct msgbuf *) (cp + size - sizeof(*msgbufp));
  691         if (msgbufp->msg_magic != MSG_MAGIC || msgbufp->msg_ptr != cp) {
  692                 bzero(cp, size);
  693                 msgbufp->msg_magic = MSG_MAGIC;
  694                 msgbufp->msg_size = (char *)msgbufp - cp;
  695                 msgbufp->msg_ptr = cp;
  696         }
  697         msgbufmapped = 1;
  698 }
  699 
  700 #include "opt_ddb.h"
  701 #ifdef DDB
  702 #include <ddb/ddb.h>
  703 
  704 DB_SHOW_COMMAND(msgbuf, db_show_msgbuf)
  705 {
  706         int i, j;
  707 
  708         if (!msgbufmapped) {
  709                 db_printf("msgbuf not mapped yet\n");
  710                 return;
  711         }
  712         db_printf("msgbufp = %p\n", msgbufp);
  713         db_printf("magic = %x, size = %d, r= %d, w = %d, ptr = %p\n",
  714             msgbufp->msg_magic, msgbufp->msg_size, msgbufp->msg_bufr,
  715             msgbufp->msg_bufx, msgbufp->msg_ptr);
  716         for (i = 0; i < msgbufp->msg_size; i++) {
  717                 j = (i + msgbufp->msg_bufr) % msgbufp->msg_size;
  718                 db_printf("%c", msgbufp->msg_ptr[j]);
  719         }
  720         db_printf("\n");
  721 }
  722 
  723 #endif /* DDB */

Cache object: b5c485fc69b2cef144917808500579a2


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