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 * $Id: subr_prf.c,v 1.17 1995/08/07 08:40:49 davidg Exp $ 40 */ 41 42 #include <sys/param.h> 43 #include <sys/systm.h> 44 #include <sys/reboot.h> 45 #include <sys/msgbuf.h> 46 #include <sys/proc.h> 47 #include <sys/vnode.h> 48 #include <sys/tty.h> 49 #include <sys/tprintf.h> 50 #include <sys/syslog.h> 51 #include <sys/malloc.h> 52 #include <machine/cons.h> 53 54 /* 55 * Note that stdarg.h and the ANSI style va_start macro is used for both 56 * ANSI and traditional C compilers. 57 */ 58 #include <machine/stdarg.h> 59 60 #ifdef KADB 61 #include <machine/kdbparam.h> 62 #endif 63 64 65 #define TOCONS 0x01 66 #define TOTTY 0x02 67 #define TOLOG 0x04 68 69 struct tty *constty; /* pointer to console "window" tty */ 70 71 void (*v_putc)(int) = cnputc; /* routine to putc on virtual console */ 72 73 void logpri __P((int level)); 74 static void putchar __P((int ch, int flags, struct tty *tp)); 75 static char *ksprintn __P((u_long num, int base, int *len)); 76 77 int consintr = 1; /* Ok to handle console interrupts? */ 78 79 /* 80 * Variable panicstr contains argument to first call to panic; used as flag 81 * to indicate that the kernel has already called panic. 82 */ 83 const char *panicstr; 84 85 /* 86 * Panic is called on unresolvable fatal errors. It prints "panic: mesg", 87 * and then reboots. If we are called twice, then we avoid trying to sync 88 * the disks as this often leads to recursive panics. 89 */ 90 #ifdef __GNUC__ 91 __dead /* panic() does not return */ 92 #endif 93 void 94 #ifdef __STDC__ 95 panic(const char *fmt, ...) 96 #else 97 panic(fmt, va_alist) 98 char *fmt; 99 #endif 100 { 101 int bootopt; 102 va_list ap; 103 104 bootopt = RB_AUTOBOOT | RB_DUMP; 105 if (panicstr) 106 bootopt |= RB_NOSYNC; 107 else 108 panicstr = fmt; 109 110 va_start(ap, fmt); 111 printf("panic: %r\n", fmt, ap); 112 va_end(ap); 113 114 #ifdef KGDB 115 kgdb_panic(); 116 #endif 117 #ifdef KADB 118 if (boothowto & RB_KDB) 119 kdbpanic(); 120 #endif 121 #ifdef DDB 122 Debugger ("panic"); 123 #endif 124 boot(bootopt); 125 } 126 127 /* 128 * Warn that a system table is full. 129 */ 130 void 131 tablefull(tab) 132 const char *tab; 133 { 134 135 log(LOG_ERR, "%s: table is full\n", tab); 136 } 137 138 /* 139 * Uprintf prints to the controlling terminal for the current process. 140 * It may block if the tty queue is overfull. No message is printed if 141 * the queue does not clear in a reasonable time. 142 */ 143 void 144 #ifdef __STDC__ 145 uprintf(const char *fmt, ...) 146 #else 147 uprintf(fmt, va_alist) 148 char *fmt; 149 #endif 150 { 151 register struct proc *p = curproc; 152 va_list ap; 153 154 if (p->p_flag & P_CONTROLT && p->p_session->s_ttyvp) { 155 va_start(ap, fmt); 156 kprintf(fmt, TOTTY, p->p_session->s_ttyp, ap); 157 va_end(ap); 158 } 159 } 160 161 tpr_t 162 tprintf_open(p) 163 register struct proc *p; 164 { 165 166 if (p->p_flag & P_CONTROLT && p->p_session->s_ttyvp) { 167 SESSHOLD(p->p_session); 168 return ((tpr_t) p->p_session); 169 } 170 return ((tpr_t) NULL); 171 } 172 173 void 174 tprintf_close(sess) 175 tpr_t sess; 176 { 177 178 if (sess) 179 SESSRELE((struct session *) sess); 180 } 181 182 /* 183 * tprintf prints on the controlling terminal associated 184 * with the given session. 185 */ 186 void 187 #ifdef __STDC__ 188 tprintf(tpr_t tpr, const char *fmt, ...) 189 #else 190 tprintf(tpr, fmt, va_alist) 191 tpr_t tpr; 192 char *fmt; 193 #endif 194 { 195 register struct session *sess = (struct session *)tpr; 196 struct tty *tp = NULL; 197 int flags = TOLOG; 198 va_list ap; 199 200 logpri(LOG_INFO); 201 if (sess && sess->s_ttyvp && ttycheckoutq(sess->s_ttyp, 0)) { 202 flags |= TOTTY; 203 tp = sess->s_ttyp; 204 } 205 va_start(ap, fmt); 206 kprintf(fmt, flags, tp, ap); 207 va_end(ap); 208 logwakeup(); 209 } 210 211 /* 212 * Ttyprintf displays a message on a tty; it should be used only by 213 * the tty driver, or anything that knows the underlying tty will not 214 * be revoke(2)'d away. Other callers should use tprintf. 215 */ 216 void 217 #ifdef __STDC__ 218 ttyprintf(struct tty *tp, const char *fmt, ...) 219 #else 220 ttyprintf(tp, fmt, va_alist) 221 struct tty *tp; 222 char *fmt; 223 #endif 224 { 225 va_list ap; 226 227 va_start(ap, fmt); 228 kprintf(fmt, TOTTY, tp, ap); 229 va_end(ap); 230 } 231 232 extern int log_open; 233 234 /* 235 * Log writes to the log buffer, and guarantees not to sleep (so can be 236 * called by interrupt routines). If there is no process reading the 237 * log yet, it writes to the console also. 238 */ 239 void 240 #ifdef __STDC__ 241 log(int level, const char *fmt, ...) 242 #else 243 log(level, fmt, va_alist) 244 int level; 245 char *fmt; 246 #endif 247 { 248 register int s; 249 va_list ap; 250 251 s = splhigh(); 252 logpri(level); 253 va_start(ap, fmt); 254 kprintf(fmt, TOLOG, NULL, ap); 255 splx(s); 256 va_end(ap); 257 if (!log_open) { 258 va_start(ap, fmt); 259 kprintf(fmt, TOCONS, NULL, ap); 260 va_end(ap); 261 } 262 logwakeup(); 263 } 264 265 void 266 logpri(level) 267 int level; 268 { 269 register char *p; 270 271 putchar('<', TOLOG, NULL); 272 for (p = ksprintn((u_long)level, 10, NULL); *p;) 273 putchar(*p--, TOLOG, NULL); 274 putchar('>', TOLOG, NULL); 275 } 276 277 void 278 #ifdef __STDC__ 279 addlog(const char *fmt, ...) 280 #else 281 addlog(fmt, va_alist) 282 char *fmt; 283 #endif 284 { 285 register int s; 286 va_list ap; 287 288 s = splhigh(); 289 va_start(ap, fmt); 290 kprintf(fmt, TOLOG, NULL, ap); 291 splx(s); 292 va_end(ap); 293 if (!log_open) { 294 va_start(ap, fmt); 295 kprintf(fmt, TOCONS, NULL, ap); 296 va_end(ap); 297 } 298 logwakeup(); 299 } 300 301 void 302 #ifdef __STDC__ 303 printf(const char *fmt, ...) 304 #else 305 printf(fmt, va_alist) 306 char *fmt; 307 #endif 308 { 309 va_list ap; 310 register int savintr; 311 312 savintr = consintr; /* disable interrupts */ 313 consintr = 0; 314 va_start(ap, fmt); 315 kprintf(fmt, TOCONS | TOLOG, NULL, ap); 316 va_end(ap); 317 if (!panicstr) 318 logwakeup(); 319 consintr = savintr; /* reenable interrupts */ 320 } 321 322 /* 323 * Scaled down version of printf(3). 324 * 325 * Two additional formats: 326 * 327 * The format %b is supported to decode error registers. 328 * Its usage is: 329 * 330 * printf("reg=%b\n", regval, "<base><arg>*"); 331 * 332 * where <base> is the output base expressed as a control character, e.g. 333 * \10 gives octal; \20 gives hex. Each arg is a sequence of characters, 334 * the first of which gives the bit number to be inspected (origin 1), and 335 * the next characters (up to a control character, i.e. a character <= 32), 336 * give the name of the register. Thus: 337 * 338 * kprintf("reg=%b\n", 3, "\10\2BITTWO\1BITONE\n"); 339 * 340 * would produce output: 341 * 342 * reg=3<BITTWO,BITONE> 343 * 344 * The format %r passes an additional format string and argument list 345 * recursively. Its usage is: 346 * 347 * fn(char *fmt, ...) 348 * { 349 * va_list ap; 350 * va_start(ap, fmt); 351 * printf("prefix: %r: suffix\n", fmt, ap); 352 * va_end(ap); 353 * } 354 * 355 * Space or zero padding and a field width are supported for the numeric 356 * formats only. 357 */ 358 void 359 kprintf(fmt, flags, tp, ap) 360 register const char *fmt; 361 int flags; 362 struct tty *tp; 363 va_list ap; 364 { 365 register char *p, *q; 366 register int ch, n; 367 u_long ul; 368 int base, lflag, tmp, width; 369 char padc; 370 371 if (fmt == NULL) 372 fmt = "(fmt null)\n"; 373 for (;;) { 374 padc = ' '; 375 width = 0; 376 while ((ch = *(u_char *)fmt++) != '%') { 377 if (ch == '\0') 378 return; 379 putchar(ch, flags, tp); 380 } 381 lflag = 0; 382 reswitch: switch (ch = *(u_char *)fmt++) { 383 case '0': 384 padc = '0'; 385 goto reswitch; 386 case '1': case '2': case '3': case '4': 387 case '5': case '6': case '7': case '8': case '9': 388 for (width = 0;; ++fmt) { 389 width = width * 10 + ch - '0'; 390 ch = *fmt; 391 if (ch < '0' || ch > '9') 392 break; 393 } 394 goto reswitch; 395 case 'l': 396 lflag = 1; 397 goto reswitch; 398 case 'b': 399 ul = va_arg(ap, int); 400 p = va_arg(ap, char *); 401 for (q = ksprintn(ul, *p++, NULL); *q;) 402 putchar(*q--, flags, tp); 403 404 if (!ul) 405 break; 406 407 for (tmp = 0; *p;) { 408 n = *p++; 409 if (ul & (1 << (n - 1))) { 410 putchar(tmp ? ',' : '<', flags, tp); 411 for (; (n = *p) > ' '; ++p) 412 putchar(n, flags, tp); 413 tmp = 1; 414 } else 415 for (; *p > ' '; ++p) 416 continue; 417 } 418 if (tmp) 419 putchar('>', flags, tp); 420 break; 421 case 'c': 422 putchar(va_arg(ap, int), flags, tp); 423 break; 424 case 'r': 425 p = va_arg(ap, char *); 426 kprintf(p, flags, tp, va_arg(ap, va_list)); 427 break; 428 case 's': 429 p = va_arg(ap, char *); 430 if (p == NULL) 431 p = "(null)"; 432 while (*p) 433 putchar(*p++, flags, tp); 434 break; 435 case 'd': 436 ul = lflag ? va_arg(ap, long) : va_arg(ap, int); 437 if ((long)ul < 0) { 438 putchar('-', flags, tp); 439 ul = -(long)ul; 440 } 441 base = 10; 442 goto number; 443 case 'o': 444 ul = lflag ? va_arg(ap, u_long) : va_arg(ap, u_int); 445 base = 8; 446 goto number; 447 case 'p': 448 ul = (u_long)va_arg(ap, void *); 449 base = 16; 450 putchar('0', flags, tp); 451 putchar('x', flags, tp); 452 goto number; 453 case 'u': 454 ul = lflag ? va_arg(ap, u_long) : va_arg(ap, u_int); 455 base = 10; 456 goto number; 457 case 'x': 458 ul = lflag ? va_arg(ap, u_long) : va_arg(ap, u_int); 459 base = 16; 460 number: p = ksprintn(ul, base, &tmp); 461 if (width && (width -= tmp) > 0) 462 while (width--) 463 putchar(padc, flags, tp); 464 while (*p) 465 putchar(*p--, flags, tp); 466 break; 467 default: 468 putchar('%', flags, tp); 469 if (lflag) 470 putchar('l', flags, tp); 471 /* FALLTHROUGH */ 472 case '%': 473 putchar(ch, flags, tp); 474 } 475 } 476 } 477 478 /* 479 * Print a character on console or users terminal. If destination is 480 * the console then the last MSGBUFS characters are saved in msgbuf for 481 * inspection later. 482 */ 483 static void 484 putchar(c, flags, tp) 485 register int c; 486 int flags; 487 struct tty *tp; 488 { 489 register struct msgbuf *mbp; 490 491 if (panicstr) 492 constty = NULL; 493 if ((flags & TOCONS) && tp == NULL && constty) { 494 tp = constty; 495 flags |= TOTTY; 496 } 497 if ((flags & TOTTY) && tp && tputchar(c, tp) < 0 && 498 (flags & TOCONS) && tp == constty) 499 constty = NULL; 500 if ((flags & TOLOG) && 501 c != '\0' && c != '\r' && c != 0177 && msgbufmapped) { 502 mbp = msgbufp; 503 if (mbp->msg_magic != MSG_MAGIC || 504 mbp->msg_bufx >= MSG_BSIZE || 505 mbp->msg_bufr >= MSG_BSIZE) { 506 bzero(mbp, sizeof(struct msgbuf)); 507 mbp->msg_magic = MSG_MAGIC; 508 } 509 mbp->msg_bufc[mbp->msg_bufx++] = c; 510 if (mbp->msg_bufx >= MSG_BSIZE) 511 mbp->msg_bufx = 0; 512 /* If the buffer is full, keep the most recent data. */ 513 if (mbp->msg_bufr == mbp->msg_bufx) { 514 if (++mbp->msg_bufr >= MSG_BSIZE) 515 mbp->msg_bufr = 0; 516 } 517 } 518 if ((flags & TOCONS) && constty == NULL && c != '\0') 519 (*v_putc)(c); 520 } 521 522 /* 523 * Scaled down version of sprintf(3). 524 */ 525 #ifdef __STDC__ 526 int 527 sprintf(char *buf, const char *cfmt, ...) 528 #else 529 int 530 sprintf(buf, cfmt, va_alist) 531 char *buf, *cfmt; 532 #endif 533 { 534 register const char *fmt = cfmt; 535 register char *p, *bp; 536 register int ch, base; 537 u_long ul; 538 int lflag; 539 va_list ap; 540 541 va_start(ap, cfmt); 542 for (bp = buf; ; ) { 543 while ((ch = *(u_char *)fmt++) != '%') 544 if ((*bp++ = ch) == '\0') 545 return ((bp - buf) - 1); 546 547 lflag = 0; 548 reswitch: switch (ch = *(u_char *)fmt++) { 549 case 'l': 550 lflag = 1; 551 goto reswitch; 552 case 'c': 553 *bp++ = va_arg(ap, int); 554 break; 555 case 's': 556 p = va_arg(ap, char *); 557 while (*p) 558 *bp++ = *p++; 559 break; 560 case 'd': 561 ul = lflag ? va_arg(ap, long) : va_arg(ap, int); 562 if ((long)ul < 0) { 563 *bp++ = '-'; 564 ul = -(long)ul; 565 } 566 base = 10; 567 goto number; 568 break; 569 case 'o': 570 ul = lflag ? va_arg(ap, u_long) : va_arg(ap, u_int); 571 base = 8; 572 goto number; 573 break; 574 case 'p': 575 ul = (u_long)va_arg(ap, void *); 576 base = 16; 577 *bp++ = '0'; 578 *bp++ = 'x'; 579 goto number; 580 case 'u': 581 ul = lflag ? va_arg(ap, u_long) : va_arg(ap, u_int); 582 base = 10; 583 goto number; 584 break; 585 case 'x': 586 ul = lflag ? va_arg(ap, u_long) : va_arg(ap, u_int); 587 base = 16; 588 number: for (p = ksprintn(ul, base, NULL); *p;) 589 *bp++ = *p--; 590 break; 591 default: 592 *bp++ = '%'; 593 if (lflag) 594 *bp++ = 'l'; 595 /* FALLTHROUGH */ 596 case '%': 597 *bp++ = ch; 598 } 599 } 600 va_end(ap); 601 } 602 603 /* 604 * Put a number (base <= 16) in a buffer in reverse order; return an 605 * optional length and a pointer to the NULL terminated (preceded?) 606 * buffer. 607 */ 608 static char * 609 ksprintn(ul, base, lenp) 610 register u_long ul; 611 register int base, *lenp; 612 { /* A long in base 8, plus NULL. */ 613 static char buf[sizeof(long) * NBBY / 3 + 2]; 614 register char *p; 615 616 p = buf; 617 do { 618 *++p = "0123456789abcdef"[ul % base]; 619 } while (ul /= base); 620 if (lenp) 621 *lenp = p - buf; 622 return (p); 623 } 624