| 441 | } |
| 442 | |
| 443 | static void |
| 444 | putbuf(int c, struct putchar_arg *ap) |
| 445 | { |
| 446 | /* Check if no console output buffer was provided. */ |
| 447 | if (ap->p_bufr == NULL) { |
| 448 | /* Output direct to the console. */ |
| 449 | if (ap->flags & TOCONS) |
| 450 | cnputc(c); |
| 451 | |
| 452 | if (ap->flags & TOLOG) |
| 453 | msglogchar(c, ap->pri); |
| 454 | } else { |
| 455 | /* Buffer the character: */ |
| 456 | *ap->p_next++ = c; |
| 457 | ap->remain--; |
| 458 | |
| 459 | /* Always leave the buffer zero terminated. */ |
| 460 | *ap->p_next = '\0'; |
| 461 | |
| 462 | /* Check if the buffer needs to be flushed. */ |
| 463 | if (ap->remain == 2 || c == '\n') { |
| 464 | prf_putbuf(ap->p_bufr, ap->flags, ap->pri); |
| 465 | |
| 466 | ap->p_next = ap->p_bufr; |
| 467 | ap->remain = ap->n_bufr; |
| 468 | *ap->p_next = '\0'; |
| 469 | } |
| 470 | |
| 471 | /* |
| 472 | * Since we fill the buffer up one character at a time, |
| 473 | * this should not happen. We should always catch it when |
| 474 | * ap->remain == 2 (if not sooner due to a newline), flush |
| 475 | * the buffer and move on. One way this could happen is |
| 476 | * if someone sets PRINTF_BUFR_SIZE to 1 or something |
| 477 | * similarly silly. |
| 478 | */ |
| 479 | KASSERT(ap->remain > 2, ("Bad buffer logic, remain = %zd", |
| 480 | ap->remain)); |
| 481 | } |
| 482 | } |
| 483 | |
| 484 | /* |
| 485 | * Print a character on console or users terminal. If destination is |
no test coverage detected