subr_prf.c (209949) | subr_prf.c (222537) |
---|---|
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. --- 21 unchanged lines hidden (view full) --- 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 * 34 * @(#)subr_prf.c 8.3 (Berkeley) 1/21/94 35 */ 36 37#include <sys/cdefs.h> | 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. --- 21 unchanged lines hidden (view full) --- 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 * 34 * @(#)subr_prf.c 8.3 (Berkeley) 1/21/94 35 */ 36 37#include <sys/cdefs.h> |
38__FBSDID("$FreeBSD: head/sys/kern/subr_prf.c 209949 2010-07-12 15:32:45Z jkim $"); | 38__FBSDID("$FreeBSD: head/sys/kern/subr_prf.c 222537 2011-05-31 17:29:58Z ken $"); |
39 40#include "opt_ddb.h" 41#include "opt_printf.h" 42 43#include <sys/param.h> 44#include <sys/systm.h> 45#include <sys/lock.h> 46#include <sys/kdb.h> --- 42 unchanged lines hidden (view full) --- 89struct snprintf_arg { 90 char *str; 91 size_t remain; 92}; 93 94extern int log_open; 95 96static void msglogchar(int c, int pri); | 39 40#include "opt_ddb.h" 41#include "opt_printf.h" 42 43#include <sys/param.h> 44#include <sys/systm.h> 45#include <sys/lock.h> 46#include <sys/kdb.h> --- 42 unchanged lines hidden (view full) --- 89struct snprintf_arg { 90 char *str; 91 size_t remain; 92}; 93 94extern int log_open; 95 96static void msglogchar(int c, int pri); |
97static void msglogstr(char *str, int pri, int filter_cr); |
|
97static void putchar(int ch, void *arg); 98static char *ksprintn(char *nbuf, uintmax_t num, int base, int *len, int upper); 99static void snprintf_func(int ch, void *arg); 100 101static int msgbufmapped; /* Set when safe to use msgbuf */ 102int msgbuftrigger; 103 104static int log_console_output = 1; 105TUNABLE_INT("kern.log_console_output", &log_console_output); 106SYSCTL_INT(_kern, OID_AUTO, log_console_output, CTLFLAG_RW, 107 &log_console_output, 0, "Duplicate console output to the syslog."); 108 | 98static void putchar(int ch, void *arg); 99static char *ksprintn(char *nbuf, uintmax_t num, int base, int *len, int upper); 100static void snprintf_func(int ch, void *arg); 101 102static int msgbufmapped; /* Set when safe to use msgbuf */ 103int msgbuftrigger; 104 105static int log_console_output = 1; 106TUNABLE_INT("kern.log_console_output", &log_console_output); 107SYSCTL_INT(_kern, OID_AUTO, log_console_output, CTLFLAG_RW, 108 &log_console_output, 0, "Duplicate console output to the syslog."); 109 |
110/* 111 * See the comment in log_console() below for more explanation of this. 112 */ 113static int log_console_add_linefeed = 0; 114TUNABLE_INT("kern.log_console_add_linefeed", &log_console_add_linefeed); 115SYSCTL_INT(_kern, OID_AUTO, log_console_add_linefeed, CTLFLAG_RW, 116 &log_console_add_linefeed, 0, "log_console() adds extra newlines."); 117 |
|
109static int always_console_output = 0; 110TUNABLE_INT("kern.always_console_output", &always_console_output); 111SYSCTL_INT(_kern, OID_AUTO, always_console_output, CTLFLAG_RW, 112 &always_console_output, 0, "Always output to console despite TIOCCONS."); 113 114/* 115 * Warn that a system table is full. 116 */ --- 118 unchanged lines hidden (view full) --- 235 * called by interrupt routines). If there is no process reading the 236 * log yet, it writes to the console also. 237 */ 238void 239log(int level, const char *fmt, ...) 240{ 241 va_list ap; 242 struct putchar_arg pca; | 118static int always_console_output = 0; 119TUNABLE_INT("kern.always_console_output", &always_console_output); 120SYSCTL_INT(_kern, OID_AUTO, always_console_output, CTLFLAG_RW, 121 &always_console_output, 0, "Always output to console despite TIOCCONS."); 122 123/* 124 * Warn that a system table is full. 125 */ --- 118 unchanged lines hidden (view full) --- 244 * called by interrupt routines). If there is no process reading the 245 * log yet, it writes to the console also. 246 */ 247void 248log(int level, const char *fmt, ...) 249{ 250 va_list ap; 251 struct putchar_arg pca; |
252#ifdef PRINTF_BUFR_SIZE 253 char bufr[PRINTF_BUFR_SIZE]; 254#endif |
|
243 244 pca.tty = NULL; 245 pca.pri = level; 246 pca.flags = log_open ? TOLOG : TOCONS; | 255 256 pca.tty = NULL; 257 pca.pri = level; 258 pca.flags = log_open ? TOLOG : TOCONS; |
259#ifdef PRINTF_BUFR_SIZE 260 pca.p_bufr = bufr; 261 pca.p_next = pca.p_bufr; 262 pca.n_bufr = sizeof(bufr); 263 pca.remain = sizeof(bufr); 264 *pca.p_next = '\0'; 265#else |
|
247 pca.p_bufr = NULL; | 266 pca.p_bufr = NULL; |
267#endif |
|
248 249 va_start(ap, fmt); 250 kvprintf(fmt, putchar, &pca, 10, ap); 251 va_end(ap); 252 | 268 269 va_start(ap, fmt); 270 kvprintf(fmt, putchar, &pca, 10, ap); 271 va_end(ap); 272 |
273#ifdef PRINTF_BUFR_SIZE 274 /* Write any buffered console/log output: */ 275 if (*pca.p_bufr != '\0') { 276 if (pca.flags & TOLOG) 277 msglogstr(pca.p_bufr, level, /*filter_cr*/1); 278 279 if (pca.flags & TOCONS) 280 cnputs(pca.p_bufr); 281 } 282#endif |
|
253 msgbuftrigger = 1; 254} 255 256#define CONSCHUNK 128 257 258void 259log_console(struct uio *uio) 260{ | 283 msgbuftrigger = 1; 284} 285 286#define CONSCHUNK 128 287 288void 289log_console(struct uio *uio) 290{ |
261 int c, i, error, nl; | 291 int c, error, nl; |
262 char *consbuffer; 263 int pri; 264 265 if (!log_console_output) 266 return; 267 268 pri = LOG_INFO | LOG_CONSOLE; 269 uio = cloneuio(uio); 270 consbuffer = malloc(CONSCHUNK, M_TEMP, M_WAITOK); 271 272 nl = 0; 273 while (uio->uio_resid > 0) { | 292 char *consbuffer; 293 int pri; 294 295 if (!log_console_output) 296 return; 297 298 pri = LOG_INFO | LOG_CONSOLE; 299 uio = cloneuio(uio); 300 consbuffer = malloc(CONSCHUNK, M_TEMP, M_WAITOK); 301 302 nl = 0; 303 while (uio->uio_resid > 0) { |
274 c = imin(uio->uio_resid, CONSCHUNK); | 304 c = imin(uio->uio_resid, CONSCHUNK - 1); |
275 error = uiomove(consbuffer, c, uio); 276 if (error != 0) 277 break; | 305 error = uiomove(consbuffer, c, uio); 306 if (error != 0) 307 break; |
278 for (i = 0; i < c; i++) { 279 msglogchar(consbuffer[i], pri); 280 if (consbuffer[i] == '\n') 281 nl = 1; 282 else 283 nl = 0; 284 } | 308 /* Make sure we're NUL-terminated */ 309 consbuffer[c] = '\0'; 310 if (consbuffer[c - 1] == '\n') 311 nl = 1; 312 else 313 nl = 0; 314 msglogstr(consbuffer, pri, /*filter_cr*/ 1); |
285 } | 315 } |
286 if (!nl) 287 msglogchar('\n', pri); | 316 /* 317 * The previous behavior in log_console() is preserved when 318 * log_console_add_linefeed is non-zero. For that behavior, if an 319 * individual console write came in that was not terminated with a 320 * line feed, it would add a line feed. 321 * 322 * This results in different data in the message buffer than 323 * appears on the system console (which doesn't add extra line feed 324 * characters). 325 * 326 * A number of programs and rc scripts write a line feed, or a period 327 * and a line feed when they have completed their operation. On 328 * the console, this looks seamless, but when displayed with 329 * 'dmesg -a', you wind up with output that looks like this: 330 * 331 * Updating motd: 332 * . 333 * 334 * On the console, it looks like this: 335 * Updating motd:. 336 * 337 * We could add logic to detect that situation, or just not insert 338 * the extra newlines. Set the kern.log_console_add_linefeed 339 * sysctl/tunable variable to get the old behavior. 340 */ 341 if (!nl && log_console_add_linefeed) { 342 consbuffer[0] = '\n'; 343 consbuffer[1] = '\0'; 344 msglogstr(consbuffer, pri, /*filter_cr*/ 1); 345 } |
288 msgbuftrigger = 1; 289 free(uio, M_IOV); 290 free(consbuffer, M_TEMP); 291 return; 292} 293 294int 295printf(const char *fmt, ...) --- 29 unchanged lines hidden (view full) --- 325#else 326 /* Don't buffer console output. */ 327 pca.p_bufr = NULL; 328#endif 329 330 retval = kvprintf(fmt, putchar, &pca, 10, ap); 331 332#ifdef PRINTF_BUFR_SIZE | 346 msgbuftrigger = 1; 347 free(uio, M_IOV); 348 free(consbuffer, M_TEMP); 349 return; 350} 351 352int 353printf(const char *fmt, ...) --- 29 unchanged lines hidden (view full) --- 383#else 384 /* Don't buffer console output. */ 385 pca.p_bufr = NULL; 386#endif 387 388 retval = kvprintf(fmt, putchar, &pca, 10, ap); 389 390#ifdef PRINTF_BUFR_SIZE |
333 /* Write any buffered console output: */ 334 if (*pca.p_bufr != '\0') | 391 /* Write any buffered console/log output: */ 392 if (*pca.p_bufr != '\0') { |
335 cnputs(pca.p_bufr); | 393 cnputs(pca.p_bufr); |
394 msglogstr(pca.p_bufr, pca.pri, /*filter_cr*/ 1); 395 } |
|
336#endif 337 338 if (!panicstr) 339 msgbuftrigger = 1; 340 341 return (retval); 342} 343 344static void | 396#endif 397 398 if (!panicstr) 399 msgbuftrigger = 1; 400 401 return (retval); 402} 403 404static void |
345putcons(int c, struct putchar_arg *ap) | 405putbuf(int c, struct putchar_arg *ap) |
346{ 347 /* Check if no console output buffer was provided. */ | 406{ 407 /* Check if no console output buffer was provided. */ |
348 if (ap->p_bufr == NULL) | 408 if (ap->p_bufr == NULL) { |
349 /* Output direct to the console. */ | 409 /* Output direct to the console. */ |
350 cnputc(c); 351 else { | 410 if (ap->flags & TOCONS) 411 cnputc(c); 412 413 if (ap->flags & TOLOG) 414 msglogchar(c, ap->pri); 415 } else { |
352 /* Buffer the character: */ | 416 /* Buffer the character: */ |
353 if (c == '\n') { 354 *ap->p_next++ = '\r'; 355 ap->remain--; 356 } | |
357 *ap->p_next++ = c; 358 ap->remain--; 359 360 /* Always leave the buffer zero terminated. */ 361 *ap->p_next = '\0'; 362 363 /* Check if the buffer needs to be flushed. */ | 417 *ap->p_next++ = c; 418 ap->remain--; 419 420 /* Always leave the buffer zero terminated. */ 421 *ap->p_next = '\0'; 422 423 /* Check if the buffer needs to be flushed. */ |
364 if (ap->remain < 3 || c == '\n') { 365 cnputs(ap->p_bufr); | 424 if (ap->remain == 2 || c == '\n') { 425 426 if (ap->flags & TOLOG) 427 msglogstr(ap->p_bufr, ap->pri, /*filter_cr*/1); 428 429 if (ap->flags & TOCONS) { 430 if ((panicstr == NULL) && (constty != NULL)) 431 msgbuf_addstr(&consmsgbuf, -1, 432 ap->p_bufr, /*filter_cr*/ 0); 433 434 if ((constty == NULL) ||(always_console_output)) 435 cnputs(ap->p_bufr); 436 } 437 |
366 ap->p_next = ap->p_bufr; 367 ap->remain = ap->n_bufr; 368 *ap->p_next = '\0'; 369 } | 438 ap->p_next = ap->p_bufr; 439 ap->remain = ap->n_bufr; 440 *ap->p_next = '\0'; 441 } |
442 443 /* 444 * Since we fill the buffer up one character at a time, 445 * this should not happen. We should always catch it when 446 * ap->remain == 2 (if not sooner due to a newline), flush 447 * the buffer and move on. One way this could happen is 448 * if someone sets PRINTF_BUFR_SIZE to 1 or something 449 * similarly silly. 450 */ 451 KASSERT(ap->remain > 2, ("Bad buffer logic, remain = %zd", 452 ap->remain)); |
|
370 } 371} 372 373/* 374 * Print a character on console or users terminal. If destination is 375 * the console then the last bunch of characters are saved in msgbuf for 376 * inspection later. 377 */ 378static void 379putchar(int c, void *arg) 380{ 381 struct putchar_arg *ap = (struct putchar_arg*) arg; 382 struct tty *tp = ap->tty; 383 int flags = ap->flags; | 453 } 454} 455 456/* 457 * Print a character on console or users terminal. If destination is 458 * the console then the last bunch of characters are saved in msgbuf for 459 * inspection later. 460 */ 461static void 462putchar(int c, void *arg) 463{ 464 struct putchar_arg *ap = (struct putchar_arg*) arg; 465 struct tty *tp = ap->tty; 466 int flags = ap->flags; |
467 int putbuf_done = 0; |
|
384 385 /* Don't use the tty code after a panic or while in ddb. */ 386 if (kdb_active) { 387 if (c != '\0') 388 cnputc(c); | 468 469 /* Don't use the tty code after a panic or while in ddb. */ 470 if (kdb_active) { 471 if (c != '\0') 472 cnputc(c); |
389 } else if (panicstr || ((flags & TOCONS) && constty == NULL)) { 390 if (c != '\0') 391 putcons(c, ap); | |
392 } else { | 473 } else { |
393 if ((flags & TOTTY) && tp != NULL) | 474 if ((panicstr == NULL) && (flags & TOTTY) && (tp != NULL)) |
394 tty_putchar(tp, c); | 475 tty_putchar(tp, c); |
476 |
|
395 if (flags & TOCONS) { | 477 if (flags & TOCONS) { |
396 if (constty != NULL) 397 msgbuf_addchar(&consmsgbuf, c); 398 if (always_console_output && c != '\0') 399 putcons(c, ap); | 478 putbuf(c, ap); 479 putbuf_done = 1; |
400 } 401 } | 480 } 481 } |
402 if ((flags & TOLOG)) 403 msglogchar(c, ap->pri); | 482 if ((flags & TOLOG) && (putbuf_done == 0)) { 483 if (c != '\0') 484 putbuf(c, ap); 485 } |
404} 405 406/* 407 * Scaled down version of sprintf(3). 408 */ 409int 410sprintf(char *buf, const char *cfmt, ...) 411{ --- 473 unchanged lines hidden (view full) --- 885 if (c == '\n') { 886 dangling = 0; 887 lastpri = -1; 888 } else { 889 dangling = 1; 890 } 891} 892 | 486} 487 488/* 489 * Scaled down version of sprintf(3). 490 */ 491int 492sprintf(char *buf, const char *cfmt, ...) 493{ --- 473 unchanged lines hidden (view full) --- 967 if (c == '\n') { 968 dangling = 0; 969 lastpri = -1; 970 } else { 971 dangling = 1; 972 } 973} 974 |
975static void 976msglogstr(char *str, int pri, int filter_cr) 977{ 978 if (!msgbufmapped) 979 return; 980 981 msgbuf_addstr(msgbufp, pri, str, filter_cr); 982} 983 |
|
893void 894msgbufinit(void *ptr, int size) 895{ 896 char *cp; 897 static struct msgbuf *oldp = NULL; 898 899 size -= sizeof(*msgbufp); 900 cp = (char *)ptr; --- 145 unchanged lines hidden --- | 984void 985msgbufinit(void *ptr, int size) 986{ 987 char *cp; 988 static struct msgbuf *oldp = NULL; 989 990 size -= sizeof(*msgbufp); 991 cp = (char *)ptr; --- 145 unchanged lines hidden --- |