fix logic error in fread
[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         FUNLOCK(f);
38         return wc;
39 }
40
41 wint_t fgetwc(FILE *f)
42 {
43         wint_t c;
44         FLOCK(f);
45         c = __fgetwc_unlocked(f);
46         FUNLOCK(f);
47         return c;
48 }
49
50 weak_alias(__fgetwc_unlocked, fgetwc_unlocked);
51 weak_alias(__fgetwc_unlocked, getwc_unlocked);