correct locking in stdio functions that tried to be lock-free
[musl] / src / stdio / fgetwc.c
1 #include "stdio_impl.h"
2
3 wint_t __fgetwc_unlocked(FILE *f)
4 {
5         mbstate_t st = { 0 };
6         wchar_t wc;
7         int c;
8         unsigned char b;
9         size_t l;
10
11         f->mode |= f->mode+1;
12
13         /* Convert character from buffer if possible */
14         if (f->rpos < f->rend) {
15                 l = mbrtowc(&wc, (void *)f->rpos, f->rend - f->rpos, &st);
16                 if (l+2 >= 2) {
17                         f->rpos += l + !l; /* l==0 means 1 byte, null */
18                         return wc;
19                 }
20                 if (l == -1) {
21                         f->rpos++;
22                         return WEOF;
23                 }
24         } else l = -2;
25
26         /* Convert character byte-by-byte */
27         while (l == -2) {
28                 b = c = getc_unlocked(f);
29                 if (c < 0) {
30                         if (!mbsinit(&st)) errno = EILSEQ;
31                         return WEOF;
32                 }
33                 l = mbrtowc(&wc, (void *)&b, 1, &st);
34                 if (l == -1) return WEOF;
35         }
36
37         return wc;
38 }
39
40 wint_t fgetwc(FILE *f)
41 {
42         wint_t c;
43         FLOCK(f);
44         c = __fgetwc_unlocked(f);
45         FUNLOCK(f);
46         return c;
47 }
48
49 weak_alias(__fgetwc_unlocked, fgetwc_unlocked);
50 weak_alias(__fgetwc_unlocked, getwc_unlocked);