PERFORCE change 102752 for review

John Birrell jb at FreeBSD.org
Sun Jul 30 00:04:19 UTC 2006


http://perforce.freebsd.org/chv.cgi?CH=102752

Change 102752 by jb at 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);
 }
 
 /*


More information about the p4-projects mailing list