1 #include "stdio_impl.h"
2 #include <limits.h>
3 #include <string.h>
4 #include <errno.h>
5 #include <stdint.h>
6
7 struct cookie {
8 char *s;
9 size_t n;
10 };
11
12 #define MIN(a, b) ((a) < (b) ? (a) : (b))
13
sn_write(FILE *f, const unsigned char *s, size_t l)14 static size_t sn_write(FILE *f, const unsigned char *s, size_t l)
15 {
16 struct cookie *c = f->cookie;
17 size_t already_size = f->wpos - f->wbase;
18 if (already_size <= c->n) {
19 size_t k = MIN(l, c->n - already_size);
20 memcpy(f->wpos, s, k);
21 f->wpos += k;
22 }
23 /* pretend to succeed, even if we discarded extra data */
24 return l;
25 }
26
vsnprintf(char *restrict s, size_t n, const char *restrict fmt, va_list ap)27 int vsnprintf(char *restrict s, size_t n, const char *restrict fmt, va_list ap)
28 {
29 unsigned char dummy[1];
30 struct cookie c = { .s = n ? s : dummy, .n = n ? n-1 : 0 };
31 FILE f = {
32 .lbf = EOF,
33 .lock = -1,
34 .buf = (unsigned char *)(n ? s: dummy),
35 .buf_size = n ? n - 1 : 0,
36 .flags = F_PBUF,
37 .cookie = &c,
38 .write = sn_write,
39 };
40
41 return vfprintf(&f, fmt, ap);
42 }
43