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