while(*bp++ = *fmt++)
while((*bp++ = *fmt++))
static char *ksprintn __P((u_long, int, int *));void kprintf __P((const char *, int, struct tty *, va_list));int consintr = 1;			/* Ok to handle console interrupts? *//* * Variable panicstr contains argument to first call to panic; used as flag * to indicate that the kernel has already called panic. */const char *panicstr;/* * Panic is called on unresolvable fatal errors.  It prints "panic: mesg", * and then reboots.  If we are called twice, then we avoid trying to sync * the disks as this often leads to recursive panics. */void#ifdef __STDC__panic(const char *fmt, ...)#elsepanic(fmt, va_alist)	char *fmt;	va_dcl#endif{	static char panicbuf[1024];	int bootopt;	va_list ap;	bootopt = RB_AUTOBOOT | RB_DUMP;	va_start(ap, fmt);	if (panicstr)		bootopt |= RB_NOSYNC;	else {		vsprintf(panicbuf, fmt, ap);		panicstr = panicbuf;	}	printf("panic: %:\n", fmt, ap);	va_end(ap);#ifdef KGDB	kgdb_panic();#endif#ifdef KADB	if (boothowto & RB_KDB)		kdbpanic();#endif#ifdef DDB	Debugger();#endif	boot(bootopt);}/* * Warn that a system table is full. */voidtablefull(tab)	const char *tab;{	log(LOG_ERR, "%s: table is full\n", tab);}/* * Uprintf prints to the controlling terminal for the current process. * It may block if the tty queue is overfull.  No message is printed if * the queue does not clear in a reasonable time. */void#ifdef __STDC__uprintf(const char *fmt, ...)#elseuprintf(fmt, va_alist)	char *fmt;	va_dcl#endif{	register struct proc *p = curproc;	va_list ap;	if (p->p_flag & P_CONTROLT && p->p_session->s_ttyvp) {		va_start(ap, fmt);		kprintf(fmt, TOTTY, p->p_session->s_ttyp, ap);		va_end(ap);	}}tpr_ttprintf_open(p)	register struct proc *p;{	if (p->p_flag & P_CONTROLT && p->p_session->s_ttyvp) {		SESSHOLD(p->p_session);		return ((tpr_t) p->p_session);	}	return ((tpr_t) NULL);}voidtprintf_close(sess)	tpr_t sess;{	if (sess)		SESSRELE((struct session *) sess);}/* * tprintf prints on the controlling terminal associated * with the given session. */void#ifdef __STDC__tprintf(tpr_t tpr, const char *fmt, ...)#elsetprintf(tpr, fmt, va_alist)	tpr_t tpr;	char *fmt;	va_dcl#endif{	register struct session *sess = (struct session *)tpr;	struct tty *tp = NULL;	int flags = TOLOG;	va_list ap;	logpri(LOG_INFO);	if (sess && sess->s_ttyvp && ttycheckoutq(sess->s_ttyp, 0)) {		flags |= TOTTY;		tp = sess->s_ttyp;	}	va_start(ap, fmt);	kprintf(fmt, flags, tp, ap);	va_end(ap);	logwakeup();}/* * Ttyprintf displays a message on a tty; it should be used only by * the tty driver, or anything that knows the underlying tty will not * be revoke(2)'d away.  Other callers should use tprintf. */void#ifdef __STDC__ttyprintf(struct tty *tp, const char *fmt, ...)#elsettyprintf(tp, fmt, va_alist)	struct tty *tp;	char *fmt;	va_dcl#endif{	va_list ap;	va_start(ap, fmt);	kprintf(fmt, TOTTY, tp, ap);	va_end(ap);}extern	int log_open;/* * Log writes to the log buffer, and guarantees not to sleep (so can be * called by interrupt routines).  If there is no process reading the * log yet, it writes to the console also. */void#ifdef __STDC__log(int level, const char *fmt, ...)#elselog(level, fmt, va_alist)	int level;	char *fmt;	va_dcl#endif{	register int s;	va_list ap;	s = splhigh();	logpri(level);	va_start(ap, fmt);	kprintf(fmt, TOLOG, NULL, ap);	splx(s);	va_end(ap);	if (!log_open) {		va_start(ap, fmt);		kprintf(fmt, TOCONS, NULL, ap);		va_end(ap);	}	logwakeup();}voidlogpri(level)	int level;{	register int ch;	register char *p;	putchar('<', TOLOG, NULL);	for (p = ksprintn((u_long)level, 10, NULL); (ch = *p--) != 0;)		putchar(ch, TOLOG, NULL);	putchar('>', TOLOG, NULL);}int#ifdef __STDC__addlog(const char *fmt, ...)#elseaddlog(fmt, va_alist)	char *fmt;	va_dcl#endif{	register int s;	va_list ap;	s = splhigh();	va_start(ap, fmt);	kprintf(fmt, TOLOG, NULL, ap);	splx(s);	va_end(ap);	if (!log_open) {		va_start(ap, fmt);		kprintf(fmt, TOCONS, NULL, ap);		va_end(ap);	}	logwakeup();	return (0);}int#ifdef __STDC__printf(const char *fmt, ...)#elseprintf(fmt, va_alist)	char *fmt;	va_dcl#endif{	va_list ap;	register int savintr;	savintr = consintr;		/* disable interrupts */	consintr = 0;	va_start(ap, fmt);	kprintf(fmt, TOCONS | TOLOG, NULL, ap);	va_end(ap);	if (!panicstr)		logwakeup();	consintr = savintr;		/* reenable interrupts */	return (0);}/* * Scaled down version of printf(3). * * Two additional formats: * * The format %b is supported to decode error registers. * Its usage is: * *	printf("reg=%b\n", regval, "<base><arg>*"); * * where <base> is the output base expressed as a control character, e.g. * \10 gives octal; \20 gives hex.  Each arg is a sequence of characters, * the first of which gives the bit number to be inspected (origin 1), and * the next characters (up to a control character, i.e. a character <= 32), * give the name of the register.  Thus: * *	kprintf("reg=%b\n", 3, "\10\2BITTWO\1BITONE\n"); * * would produce output: * *	reg=3<BITTWO,BITONE> * * The format %: passes an additional format string and argument list * recursively.  Its usage is: * * fn(char *fmt, ...) * { *	va_list ap; *	va_start(ap, fmt); *	printf("prefix: %: suffix\n", fmt, ap); *	va_end(ap); * } * * Space or zero padding and a field width are supported for the numeric * formats only. */voidkprintf(fmt, flags, tp, ap)	register const char *fmt;	int flags;	struct tty *tp;	va_list ap;{	register char *p, *q;	register int ch, n;	u_long ul;	int base, lflag, tmp, width;	char padc;	for (;;) {		padc = ' ';		width = 0;		while ((ch = *(u_char *)fmt++) != '%') {			if (ch == '\0')				return;			putchar(ch, flags, tp);		}		lflag = 0;reswitch:	switch (ch = *(u_char *)fmt++) {		case '\0':			while(*--fmt != '%')				;			fmt++;			putchar('%', flags, tp);			continue;		case '0':			padc = '0';			goto reswitch;		case '1': case '2': case '3': case '4':		case '5': case '6': case '7': case '8': case '9':			for (width = 0;; ++fmt) {				width = width * 10 + ch - '0';				ch = *fmt;				if (ch < '0' || ch > '9')					break;			}			goto reswitch;		case 'l':			lflag = 1;			goto reswitch;		case 'b':			ul = va_arg(ap, int);			p = va_arg(ap, char *);			for (q = ksprintn(ul, *p++, NULL); (ch = *q--) != 0;)				putchar(ch, flags, tp);			if (!ul)				break;			for (tmp = 0; (n = *p++) != 0;) {				if (ul & (1 << (n - 1))) {					putchar(tmp ? ',' : '<', flags, tp);					for (; (n = *p) > ' '; ++p)						putchar(n, flags, tp);					tmp = 1;				} else					for (; *p > ' '; ++p)						continue;			}			if (tmp)				putchar('>', flags, tp);			break;		case 'c':			putchar(va_arg(ap, int), flags, tp);			break;		case ':':			p = va_arg(ap, char *);			kprintf(p, flags, tp, va_arg(ap, va_list));			break;		case 's':			if ((p = va_arg(ap, char *)) == NULL)				p = "(null)";			while ((ch = *p++) != 0)				putchar(ch, flags, tp);			break;		case 'd':			ul = lflag ? va_arg(ap, long) : va_arg(ap, int);			if ((long)ul < 0) {				putchar('-', flags, tp);				ul = -(long)ul;			}			base = 10;			goto number;		case 'o':			ul = lflag ? va_arg(ap, u_long) : va_arg(ap, u_int);			base = 8;			goto number;		case 'u':			ul = lflag ? va_arg(ap, u_long) : va_arg(ap, u_int);			base = 10;			goto number;		case 'p':			putchar('0', flags, tp);			putchar('x', flags, tp);			ul = (u_long)va_arg(ap, void *);			base = 16;			goto number;		case 'x':			ul = lflag ? va_arg(ap, u_long) : va_arg(ap, u_int);			base = 16;number:			p = ksprintn(ul, base, &tmp);			if (width && (width -= tmp) > 0)				while (width--)					putchar(padc, flags, tp);			while ((ch = *p--) != 0)				putchar(ch, flags, tp);			break;		default:			putchar('%', flags, tp);			if (lflag)				putchar('l', flags, tp);			/* FALLTHROUGH */		case '%':			putchar(ch, flags, tp);		}	}}/* * Print a character on console or users terminal.  If destination is * the console then the last MSGBUFS characters are saved in msgbuf for * inspection later. */static voidputchar(c, flags, tp)	register int c;	int flags;	struct tty *tp;{	extern int msgbufmapped;	register struct msgbuf *mbp;	if (panicstr)		constty = NULL;	if ((flags & TOCONS) && tp == NULL && constty) {		tp = constty;		flags |= TOTTY;	}	if ((flags & TOTTY) && tp && tputchar(c, tp) < 0 &&	    (flags & TOCONS) && tp == constty)		constty = NULL;	if ((flags & TOLOG) &&	    c != '\0' && c != '\r' && c != 0177 && msgbufmapped) {		mbp = msgbufp;		if (mbp->msg_magic != MSG_MAGIC) {			bzero((caddr_t)mbp, sizeof(*mbp));			mbp->msg_magic = MSG_MAGIC;		}		mbp->msg_bufc[mbp->msg_bufx++] = c;		if (mbp->msg_bufx < 0 || mbp->msg_bufx >= MSG_BSIZE)			mbp->msg_bufx = 0;	}	if ((flags & TOCONS) && constty == NULL && c != '\0')		(*v_putc)(c);}/* * Scaled down version of sprintf(3). */int#ifdef __STDC__vsprintf(char *buf, const char *cfmt, va_list ap)#elsevsprintf(buf, cfmt, ap)	char *buf, *cfmt;	va_list ap;#endif{	register const char *fmt = cfmt;	register char *p, *bp;	register int ch, base;	u_long ul;	int lflag, tmp, width;	char padc;	for (bp = buf; ; ) {		padc = ' ';		width = 0;		while ((ch = *(u_char *)fmt++) != '%')			if ((*bp++ = ch) == '\0')				return ((bp - buf) - 1);		lflag = 0;reswitch:	switch (ch = *(u_char *)fmt++) {		case '\0':			while(*--fmt != '%')				;			while(*bp++ = *fmt++)				;			return;		case '0':			padc = '0';			goto reswitch;		case '1': case '2': case '3': case '4':		case '5': case '6': case '7': case '8': case '9':			for (width = 0;; ++fmt) {				width = width * 10 + ch - '0';				ch = *fmt;				if (ch < '0' || ch > '9')					break;			}			goto reswitch;		case 'l':			lflag = 1;			goto reswitch;		/* case 'b': ... break; XXX */		case 'c':			*bp++ = va_arg(ap, int);			break;		/* case 'r': ... break; XXX */		case 's':			p = va_arg(ap, char *);			while ((*bp++ = *p++) != 0)				continue;			--bp;			break;		case 'd':			ul = lflag ? va_arg(ap, long) : va_arg(ap, int);			if ((long)ul < 0) {				*bp++ = '-';				ul = -(long)ul;			}			base = 10;			goto number;			break;		case 'o':			ul = lflag ? va_arg(ap, u_long) : va_arg(ap, u_int);			base = 8;			goto number;			break;		case 'u':			ul = lflag ? va_arg(ap, u_long) : va_arg(ap, u_int);			base = 10;			goto number;			break;		case 'p':			*bp++ = '0';			*bp++ = 'x';			ul = (u_long)va_arg(ap, void *);			base = 16;			goto number;		case 'x':			ul = lflag ? va_arg(ap, u_long) : va_arg(ap, u_int);			base = 16;number:			p = ksprintn(ul, base, &tmp);			if (width && (width -= tmp) > 0)				while (width--)					*bp++ = padc;			while ((ch = *p--) != 0)				*bp++ = ch;			break;		default:			*bp++ = '%';			if (lflag)				*bp++ = 'l';			/* FALLTHROUGH */		case '%':			*bp++ = ch;		}	}}int#ifdef __STDC__sprintf(char *buf, const char *cfmt, ...)#elsesprintf(buf, cfmt, va_alist)	char *buf, *cfmt;	va_dcl#endif{	va_list ap;	int ret;	va_start(ap, cfmt);	ret = vsprintf(buf, cfmt, ap);	va_end(ap);	return(ret);}/* * Put a number (base <= 16) in a buffer in reverse order; return an * optional length and a pointer to the NULL terminated (preceded?) * buffer. */static char *ksprintn(ul, base, lenp)	register u_long ul;	register int base, *lenp;{					/* A long in base 8, plus NULL. */	static char buf[sizeof(long) * NBBY / 3 + 2];	register char *p;	p = buf;	do {		*++p = "0123456789abcdef"[ul % base];	} while (ul /= base);	if (lenp)		*lenp = p - buf;	return (p);}