summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>1999-12-02 00:23:36 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>1999-12-02 00:23:36 +0000
commite60ecd9004a8e3f8ea26edb50159af2625d35c75 (patch)
tree16bd7b4125152d07711b9726c8e4d1e6ee901624 /sys
parentb350408d5407aa97bd1c50535b52d55e9b5097e2 (diff)
snprintf in kernel; assar@stacken.kth.se
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/subr_prf.c100
-rw-r--r--sys/sys/systm.h6
2 files changed, 88 insertions, 18 deletions
diff --git a/sys/kern/subr_prf.c b/sys/kern/subr_prf.c
index c97f513d8ce..5b6eb3fd762 100644
--- a/sys/kern/subr_prf.c
+++ b/sys/kern/subr_prf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: subr_prf.c,v 1.25 1999/01/11 05:12:23 millert Exp $ */
+/* $OpenBSD: subr_prf.c,v 1.26 1999/12/02 00:23:35 deraadt Exp $ */
/* $NetBSD: subr_prf.c,v 1.45 1997/10/24 18:14:25 chuck Exp $ */
/*-
@@ -94,7 +94,7 @@ extern int db_radix; /* XXX: for non-standard '%r' format */
* local prototypes
*/
-static int kprintf __P((const char *, int, struct tty *,
+static int kprintf __P((const char *, int, void *,
char *, va_list));
static void putchar __P((int, int, struct tty *));
@@ -582,6 +582,55 @@ vsprintf(buf, fmt, ap)
}
/*
+ * snprintf: print a message to a buffer
+ */
+int
+#ifdef __STDC__
+snprintf(char *buf, size_t size, const char *fmt, ...)
+#else
+snprintf(buf, size, fmt, va_alist)
+ char *buf;
+ size_t size;
+ const char *cfmt;
+ va_dcl
+#endif
+{
+ int retval;
+ va_list ap;
+ char *p;
+
+ if (size < 1)
+ return (-1);
+ p = buf + size - 1;
+ va_start(ap, fmt);
+ retval = kprintf(fmt, TOBUFONLY, &p, buf, ap);
+ va_end(ap);
+ *(p) = 0; /* null terminate */
+ return(retval);
+}
+
+/*
+ * vsnprintf: print a message to a buffer [already have va_alist]
+ */
+int
+vsnprintf(buf, size, fmt, ap)
+ char *buf;
+ size_t size;
+ const char *fmt;
+ va_list ap;
+{
+ int retval;
+ char *p;
+
+ if (size < 1)
+ return (-1);
+ p = buf + size - 1;
+ retval = kprintf(fmt, TOBUFONLY, &p, buf, ap);
+ *(p) = 0; /* null terminate */
+ return(retval);
+}
+
+/*
* kprintf: scaled down version of printf(3).
*
* this version based on vfprintf() from libc which was derived from
@@ -657,14 +706,23 @@ vsprintf(buf, fmt, ap)
flags&SHORTINT ? (u_long)(u_short)va_arg(ap, int) : \
(u_long)va_arg(ap, u_int))
-#define KPRINTF_PUTCHAR(C) \
- (oflags == TOBUFONLY) ? *sbuf++ = (C) : putchar((C), oflags, tp);
+#define KPRINTF_PUTCHAR(C) { \
+ if (oflags == TOBUFONLY) { \
+ if ((vp != NULL) && (sbuf == tailp)) { \
+ ret += 1; /* indicate error */ \
+ goto overflow; \
+ } \
+ *sbuf++ = (C); \
+ } else { \
+ putchar((C), oflags, (struct tty *)vp); \
+ } \
+}
-int
-kprintf(fmt0, oflags, tp, sbuf, ap)
+static int
+kprintf(fmt0, oflags, vp, sbuf, ap)
const char *fmt0;
int oflags;
- struct tty *tp;
+ void *vp;
char *sbuf;
va_list ap;
{
@@ -685,6 +743,11 @@ kprintf(fmt0, oflags, tp, sbuf, ap)
int size; /* size of converted field or string */
char *xdigs; /* digits for [xX] conversion */
char buf[KPRINTF_BUFSIZE]; /* space for %c, %[diouxX] */
+ char *tailp; /* tail pointer for snprintf */
+
+ tailp = NULL; /* XXX: shutup gcc */
+ if (oflags == TOBUFONLY && (vp != NULL))
+ tailp = *(char **)vp;
cp = NULL; /* XXX: shutup gcc */
size = 0; /* XXX: shutup gcc */
@@ -699,8 +762,8 @@ kprintf(fmt0, oflags, tp, sbuf, ap)
*/
for (;;) {
while (*fmt != '%' && *fmt) {
- KPRINTF_PUTCHAR(*fmt++);
ret++;
+ KPRINTF_PUTCHAR(*fmt++);
}
if (*fmt == 0)
goto done;
@@ -720,7 +783,7 @@ reswitch: switch (ch) {
case ':':
if (oflags != TOBUFONLY) {
cp = va_arg(ap, char *);
- kprintf(cp, oflags, tp,
+ kprintf(cp, oflags, vp,
NULL, va_arg(ap, va_list));
}
continue; /* no output */
@@ -743,19 +806,19 @@ reswitch: switch (ch) {
z = buf;
while (*z) {
- KPRINTF_PUTCHAR(*z++);
ret++;
+ KPRINTF_PUTCHAR(*z++);
}
if (_uquad) {
tmp = 0;
while ((n = *b++) != 0) {
if (_uquad & (1 << (n - 1))) {
- KPRINTF_PUTCHAR(tmp ? ',':'<');
ret++;
+ KPRINTF_PUTCHAR(tmp ? ',':'<');
while ((n = *b) > ' ') {
- KPRINTF_PUTCHAR(n);
ret++;
+ KPRINTF_PUTCHAR(n);
b++;
}
tmp = 1;
@@ -765,8 +828,8 @@ reswitch: switch (ch) {
}
}
if (tmp) {
- KPRINTF_PUTCHAR('>');
ret++;
+ KPRINTF_PUTCHAR('>');
}
}
continue; /* no output */
@@ -1084,6 +1147,9 @@ number: if ((dprec = prec) >= 0)
else if (flags & HEXPREFIX)
realsz+= 2;
+ /* adjust ret */
+ ret += width > realsz ? width : realsz;
+
/* right-adjusting blank padding */
if ((flags & (LADJUST|ZEROPAD)) == 0) {
n = width - realsz;
@@ -1120,12 +1186,12 @@ number: if ((dprec = prec) >= 0)
while (n-- > 0)
KPRINTF_PUTCHAR(' ');
}
-
- /* finally, adjust ret */
- ret += width > realsz ? width : realsz;
-
}
+
done:
+ if ((oflags == TOBUFONLY) && (vp != NULL))
+ *(char **)vp = sbuf;
+overflow:
return (ret);
/* NOTREACHED */
}
diff --git a/sys/sys/systm.h b/sys/sys/systm.h
index 7f6db663381..75eb54d85c5 100644
--- a/sys/sys/systm.h
+++ b/sys/sys/systm.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: systm.h,v 1.35 1999/11/12 05:58:54 angelos Exp $ */
+/* $OpenBSD: systm.h,v 1.36 1999/12/02 00:23:35 deraadt Exp $ */
/* $NetBSD: systm.h,v 1.50 1996/06/09 04:55:09 briggs Exp $ */
/*-
@@ -165,6 +165,10 @@ int vsprintf __P((char *, const char *, va_list))
__kprintf_attribute__((__format__(__kprintf__,2,3)));
int sprintf __P((char *buf, const char *, ...))
__kprintf_attribute__((__format__(__kprintf__,2,3)));
+int vsnprintf __P((char *, size_t, const char *, va_list))
+ __kprintf_attribute__((__format__(__kprintf__,3,4)));
+int snprintf __P((char *buf, size_t, const char *, ...))
+ __kprintf_attribute__((__format__(__kprintf__,3,4)));
struct tty;
void ttyprintf __P((struct tty *, const char *, ...))
__kprintf_attribute__((__format__(__kprintf__,2,3)));