1570af302Sopenharmony_ci#include "stdio_impl.h" 2570af302Sopenharmony_ci#include <limits.h> 3570af302Sopenharmony_ci#include <string.h> 4570af302Sopenharmony_ci#include <errno.h> 5570af302Sopenharmony_ci#include <stdint.h> 6570af302Sopenharmony_ci 7570af302Sopenharmony_cistruct cookie { 8570af302Sopenharmony_ci char *s; 9570af302Sopenharmony_ci size_t n; 10570af302Sopenharmony_ci}; 11570af302Sopenharmony_ci 12570af302Sopenharmony_ci#define MIN(a, b) ((a) < (b) ? (a) : (b)) 13570af302Sopenharmony_ci 14570af302Sopenharmony_cistatic size_t sn_write(FILE *f, const unsigned char *s, size_t l) 15570af302Sopenharmony_ci{ 16570af302Sopenharmony_ci struct cookie *c = f->cookie; 17570af302Sopenharmony_ci size_t already_size = f->wpos - f->wbase; 18570af302Sopenharmony_ci if (already_size <= c->n) { 19570af302Sopenharmony_ci size_t k = MIN(l, c->n - already_size); 20570af302Sopenharmony_ci memcpy(f->wpos, s, k); 21570af302Sopenharmony_ci f->wpos += k; 22570af302Sopenharmony_ci } 23570af302Sopenharmony_ci /* pretend to succeed, even if we discarded extra data */ 24570af302Sopenharmony_ci return l; 25570af302Sopenharmony_ci} 26570af302Sopenharmony_ci 27570af302Sopenharmony_ciint vsnprintf(char *restrict s, size_t n, const char *restrict fmt, va_list ap) 28570af302Sopenharmony_ci{ 29570af302Sopenharmony_ci unsigned char dummy[1]; 30570af302Sopenharmony_ci struct cookie c = { .s = n ? s : dummy, .n = n ? n-1 : 0 }; 31570af302Sopenharmony_ci FILE f = { 32570af302Sopenharmony_ci .lbf = EOF, 33570af302Sopenharmony_ci .lock = -1, 34570af302Sopenharmony_ci .buf = (unsigned char *)(n ? s: dummy), 35570af302Sopenharmony_ci .buf_size = n ? n - 1 : 0, 36570af302Sopenharmony_ci .flags = F_PBUF, 37570af302Sopenharmony_ci .cookie = &c, 38570af302Sopenharmony_ci .write = sn_write, 39570af302Sopenharmony_ci }; 40570af302Sopenharmony_ci 41570af302Sopenharmony_ci return vfprintf(&f, fmt, ap); 42570af302Sopenharmony_ci} 43