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>