summaryrefslogtreecommitdiff
path: root/src/stdio/vsnprintf.c
diff options
context:
space:
mode:
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;
+}