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