about summary refs log tree commit diff
path: root/src/stdio/vsnprintf.c
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2011-02-12 00:22:29 -0500
committerRich Felker <dalias@aerifal.cx>2011-02-12 00:22:29 -0500
commit0b44a0315b47dd8eced9f3b7f31580cf14bbfc01 (patch)
tree6eaef0d8a720fa3da580de87b647fff796fe80b3 /src/stdio/vsnprintf.c
downloadmusl-0b44a0315b47dd8eced9f3b7f31580cf14bbfc01.tar.gz
musl-0b44a0315b47dd8eced9f3b7f31580cf14bbfc01.tar.xz
musl-0b44a0315b47dd8eced9f3b7f31580cf14bbfc01.zip
initial check-in, version 0.5.0 v0.5.0
Diffstat (limited to 'src/stdio/vsnprintf.c')
-rw-r--r--src/stdio/vsnprintf.c33
1 files changed, 33 insertions, 0 deletions
diff --git a/src/stdio/vsnprintf.c b/src/stdio/vsnprintf.c
new file mode 100644
index 00000000..bda6b49b
--- /dev/null
+++ b/src/stdio/vsnprintf.c
@@ -0,0 +1,33 @@
+#include "stdio_impl.h"
+
+static size_t sn_write(FILE *f, const unsigned char *s, size_t l)
+{
+	/* pretend to succeed, but discard data */
+	return l;
+}
+
+int vsnprintf(char *s, size_t n, const char *fmt, va_list ap)
+{
+	int r;
+	FILE f;
+	unsigned char buf[1];
+
+	memset(&f, 0, sizeof(FILE));
+	f.lbf = EOF;
+	f.write = sn_write;
+	f.buf_size = 1;
+	f.buf = buf;
+	if (n > INT_MAX) {
+		errno = EOVERFLOW;
+		return -1;
+	} else if (n > 0) {
+		if (n > (char *)0+SIZE_MAX-s) n = (char *)0+SIZE_MAX-s;
+		f.wpos = s;
+		f.wbase = f.wend = s+n-1;
+		f.wstop = f.wend - 1;
+	}
+	r = vfprintf(&f, fmt, ap);
+	/* wpos points just after last byte written, or to s+n-1 (wbase) */
+	*f.wpos = 0;
+	return r;
+}