correct locking in stdio functions that tried to be lock-free
[musl] / src / stdio / vswprintf.c
1 #include "stdio_impl.h"
2
3 struct cookie {
4         wchar_t *ws;
5         size_t l;
6 };
7
8 static size_t sw_write(FILE *f, const unsigned char *s, size_t l)
9 {
10         size_t l0 = l;
11         int i = 0;
12         struct cookie *c = f->cookie;
13         if (s!=f->wbase && sw_write(f, f->wbase, f->wpos-f->wbase)==-1)
14                 return -1;
15         while (c->l && l && (i=mbtowc(c->ws, (void *)s, l))>=0) {
16                 s+=i;
17                 l-=i;
18                 c->l--;
19                 c->ws++;
20         }
21         *c->ws = 0;
22         return i<0 ? i : l0;
23 }
24
25 int vswprintf(wchar_t *restrict s, size_t n, const wchar_t *restrict fmt, va_list ap)
26 {
27         int r;
28         FILE f;
29         unsigned char buf[256];
30         struct cookie c = { s, n-1 };
31
32         memset(&f, 0, sizeof(FILE));
33         f.lbf = EOF;
34         f.write = sw_write;
35         f.buf_size = sizeof buf;
36         f.buf = buf;
37         f.lock = -1;
38         f.cookie = &c;
39         if (!n) {
40                 return -1;
41         } else if (n > INT_MAX) {
42                 errno = EOVERFLOW;
43                 return -1;
44         }
45         r = vfwprintf(&f, fmt, ap);
46         sw_write(&f, 0, 0);
47         return r>=n ? -1 : r;
48 }