OLD | NEW |
(Empty) | |
| 1 #include "stdio_impl.h" |
| 2 #include <limits.h> |
| 3 #include <string.h> |
| 4 #include <errno.h> |
| 5 #include <stdint.h> |
| 6 |
| 7 static size_t sn_write(FILE *f, const unsigned char *s, size_t l) |
| 8 { |
| 9 size_t k = f->wend - f->wpos; |
| 10 if (k > l) k = l; |
| 11 memcpy(f->wpos, s, k); |
| 12 f->wpos += k; |
| 13 /* pretend to succeed, but discard extra data */ |
| 14 return l; |
| 15 } |
| 16 |
| 17 int vsnprintf(char *restrict s, size_t n, const char *restrict fmt, va_list ap) |
| 18 { |
| 19 int r; |
| 20 char b; |
| 21 FILE f = { .lbf = EOF, .write = sn_write, .lock = -1 }; |
| 22 |
| 23 if (n-1 > INT_MAX-1) { |
| 24 if (n) { |
| 25 errno = EOVERFLOW; |
| 26 return -1; |
| 27 } |
| 28 s = &b; |
| 29 n = 1; |
| 30 } |
| 31 |
| 32 /* Ensure pointers don't wrap if "infinite" n is passed in */ |
| 33 if (n > (char *)0+SIZE_MAX-s-1) n = (char *)0+SIZE_MAX-s-1; |
| 34 f.buf_size = n; |
| 35 f.buf = f.wpos = (void *)s; |
| 36 f.wbase = f.wend = (void *)(s+n); |
| 37 r = vfprintf(&f, fmt, ap); |
| 38 |
| 39 /* Null-terminate, overwriting last char if dest buffer is full */ |
| 40 if (n) f.wpos[-(f.wpos == f.wend)] = 0; |
| 41 return r; |
| 42 } |
OLD | NEW |