Date: Sun, 30 Jul 2006 00:04:09 GMT From: John Birrell <jb@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 102752 for review Message-ID: <200607300004.k6U049iF071489@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=102752 Change 102752 by jb@jb_freebsd2 on 2006/07/30 00:03:10 Change 'printf' and 'vprintf' to write to a buffer on the stack rather than using putchar to write to the console device character by character. The limitation here is that if the 256 character buffer on the stack isn't large enough, a malloc is required and this will (obviously) only work after kmem is initialised. printfs early in the kernel boot process will need to be limited to 256 characters. More work is required to ensure the formatted string gets sent to the syslog. Affected files ... .. //depot/projects/dtrace/src/sys/kern/subr_prf.c#4 edit Differences ... ==== //depot/projects/dtrace/src/sys/kern/subr_prf.c#4 (text+ko) ==== @@ -92,7 +92,6 @@ static char *ksprintn(char *nbuf, uintmax_t num, int base, int *len, int upper); static void snprintf_func(int ch, void *arg); -static int consintr = 1; /* Ok to handle console interrupts? */ static int msgbufmapped; /* Set when safe to use msgbuf */ int msgbuftrigger; @@ -283,42 +282,79 @@ int printf(const char *fmt, ...) { + char bufr[256]; + char *p_bufr = bufr; + int s_bufr = sizeof(bufr); + int retval; va_list ap; - int savintr; - struct putchar_arg pca; - int retval; - savintr = consintr; /* disable interrupts */ - consintr = 0; + /* Try to format the string using the buffer on the stack. */ va_start(ap, fmt); - pca.tty = NULL; - pca.flags = TOCONS | TOLOG; - pca.pri = -1; - retval = kvprintf(fmt, putchar, &pca, 10, ap); + retval = vsnprintf(p_bufr, s_bufr, fmt, ap); va_end(ap); - if (!panicstr) - msgbuftrigger = 1; - consintr = savintr; /* reenable interrupts */ - return (retval); + + /* Check if the stack buffer wasn't large enough. */ + if (retval >= s_bufr) { + /* + * Allocate a temporary buffer and format that string + * into it. + */ + s_bufr = retval + 1; + p_bufr = malloc(s_bufr, M_TEMP, M_WAITOK); + va_start(ap, fmt); + retval = vsnprintf(p_bufr, s_bufr, fmt, ap); + va_end(ap); + } + + /* + * If there are characters in the string write them to put them + * to each console. + */ + if (retval > 0) + cnputs(p_bufr, retval); + + /* If a temporary buffer was allocated, free it. */ + if (p_bufr != NULL && p_bufr != bufr) + free(p_bufr, M_TEMP); + + return(retval); } int vprintf(const char *fmt, va_list ap) { - int savintr; - struct putchar_arg pca; + char bufr[256]; + char *p_bufr = bufr; + int s_bufr = sizeof(bufr); int retval; + va_list ap_cp = ap; + + /* Try to format the string using the buffer on the stack. */ + retval = vsnprintf(p_bufr, s_bufr, fmt, ap); + + /* Check if the stack buffer wasn't large enough. */ + if (retval >= s_bufr) { + /* + * Allocate a temporary buffer and format that string + * into it. + */ + s_bufr = retval + 1; + p_bufr = malloc(s_bufr, M_TEMP, M_WAITOK); + retval = vsnprintf(p_bufr, s_bufr, fmt, ap_cp); + } - savintr = consintr; /* disable interrupts */ - consintr = 0; - pca.tty = NULL; - pca.flags = TOCONS | TOLOG; - pca.pri = -1; - retval = kvprintf(fmt, putchar, &pca, 10, ap); - if (!panicstr) - msgbuftrigger = 1; - consintr = savintr; /* reenable interrupts */ - return (retval); + /* + * If there are characters in the string write them to put them + * to each console. + */ + if (retval > 0) + cnputs(p_bufr, retval); + + /* If a temporary buffer was allocated, free it. */ + if (p_bufr != NULL && p_bufr != bufr) + free(p_bufr, M_TEMP); + + return(retval); } /*
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200607300004.k6U049iF071489>