Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 4 Nov 1998 19:21:01 -0800 (PST)
From:      Archie Cobbs <archie@whistle.com>
To:        mike@smith.net.au (Mike Smith)
Cc:        hackers@FreeBSD.ORG
Subject:   Re: scanf in the kernel?
Message-ID:  <199811050321.TAA07965@bubba.whistle.com>
In-Reply-To: <199810302106.NAA02040@dingo.cdrom.com> from Mike Smith at "Oct 30, 98 01:06:10 pm"

next in thread | previous in thread | raw e-mail | index | archive | help
Mike Smith writes:
> > Seems like the kernel was missing memmove(), memcpy(), and/or memset()
> > at some point. I like using these better than bcopy()/bzero() because
> > they are more ANSI and portable...
> 
> I think there'd be some BSD traditionalist sentiment here.  But you can 
> fake them up easily enough, so if there's a compelling need this could 
> be done, yes.

Not memset() .. I think the other way around is better.. bzero()
and bcmp() should be defined in terms of the ANSI functions for
backward compatibility.. :-)

> > And what about snprintf()? Would that be hard to add to the existing
> > printf() functionality? The kernel is definitely one place you
> > don't want to overflow string buffers...
> 
> I don't know.  Want to take a quick look and tell us?

Turns out it's quite easy.. patch below. Also filed as 
a feature request: kern/8577.

-Archie

___________________________________________________________________________
Archie Cobbs   *   Whistle Communications, Inc.  *   http://www.whistle.com

Index: kern/subr_prf.c
===================================================================
RCS file: /cvs/freebsd/src/sys/kern/subr_prf.c,v
retrieving revision 1.50
diff -u -r1.50 subr_prf.c
--- subr_prf.c	1998/09/06 06:25:04	1.50
+++ subr_prf.c	1998/11/05 03:10:12
@@ -68,6 +68,8 @@
 struct putchar_arg {int flags; struct tty *tty; };
 static void  putchar __P((int ch, void *arg));
 static char *ksprintn __P((u_long num, int base, int *len));
+static void snprintf_func __P((int ch, void *arg));
+struct snprintf_arg { char *buf; size_t remain; };
 
 static int consintr = 1;		/* Ok to handle console interrupts? */
 static int msgbufmapped;		/* Set when safe to use msgbuf */
@@ -326,6 +328,47 @@
 	retval = kvprintf(cfmt, NULL, (void *)buf, 10, ap);
 	buf[retval] = '\0';
 	return retval;
+}
+
+/*
+ * Scaled down version of snprintf(3).
+ */
+int
+snprintf(char *buf, size_t max, const char *cfmt, ...)
+{
+	int retval;
+	va_list ap;
+
+	va_start(ap, cfmt);
+	retval = vsnprintf(buf, max, cfmt, ap);
+	va_end(ap);
+	return retval;
+}
+
+/*
+ * Scaled down version of vsnprintf(3).
+ */
+int
+vsnprintf(char *buf, size_t size, const char *cfmt, va_list ap)
+{
+	struct snprintf_arg info = { buf, size };
+	int retval;
+
+	retval = kvprintf(cfmt, snprintf_func, &info, 10, ap);
+	if (info.remain >= 1)
+		*info.buf++ = '\0';
+	return retval;
+}
+
+static void
+snprintf_func(int ch, void *arg)
+{
+	struct snprintf_arg *const info = (struct snprintf_arg *) arg;
+
+	if (info->remain >= 2) {
+		*info->buf++ = ch;
+		info->remain--;
+	}
 }
 
 /*
Index: sys/systm.h
===================================================================
RCS file: /cvs/freebsd/src/sys/sys/systm.h,v
retrieving revision 1.78
diff -u -r1.78 systm.h
--- systm.h	1998/10/30 05:41:15	1.78
+++ systm.h	1998/11/05 03:10:13
@@ -108,6 +108,8 @@
 void	logwakeup __P((void));
 int	printf __P((const char *, ...)) __printflike(1, 2);
 int	sprintf __P((char *buf, const char *, ...)) __printflike(2, 3);
+int	snprintf __P((char *, size_t, const char *, ...)) __printflike(3, 4);
+int	vsnprintf __P((char *, size_t, const char *, _BSD_VA_LIST_)) __printflike(3, 0);
 void	uprintf __P((const char *, ...)) __printflike(1, 2);
 void	vprintf __P((const char *, _BSD_VA_LIST_)) __printflike(1, 0);
 int     vsprintf __P((char *buf, const char *, _BSD_VA_LIST_)) __printflike(2, 0);

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199811050321.TAA07965>