1#include "stdio_impl.h" 2#include "locale_impl.h" 3#include <wchar.h> 4#include <errno.h> 5 6static wint_t __fgetwc_unlocked_internal(FILE *f) 7{ 8 mbstate_t st = { 0 }; 9 wchar_t wc; 10 int c; 11 unsigned char b; 12 size_t l; 13 14 /* Convert character from buffer if possible */ 15 if (f->rpos < f->rend) { 16 l = mbrtowc(&wc, (void *)f->rpos, f->rend - f->rpos, &st); 17 if (l+2 >= 2) { 18 f->rpos += l + !l; /* l==0 means 1 byte, null */ 19 return wc; 20 } 21 if (l == -1) { 22 f->rpos++; 23 return WEOF; 24 } 25 } else l = -2; 26 27 /* Convert character byte-by-byte */ 28 while (l == -2) { 29 b = c = getc_unlocked(f); 30 if (c < 0) { 31 if (!mbsinit(&st)) errno = EILSEQ; 32 return WEOF; 33 } 34 l = mbrtowc(&wc, (void *)&b, 1, &st); 35 if (l == -1) return WEOF; 36 } 37 38 return wc; 39} 40 41wint_t __fgetwc_unlocked(FILE *f) 42{ 43 locale_t *ploc = &CURRENT_LOCALE, loc = *ploc; 44 if (f->mode <= 0) fwide(f, 1); 45 *ploc = f->locale; 46 wchar_t wc = __fgetwc_unlocked_internal(f); 47 *ploc = loc; 48 return wc; 49} 50 51wint_t fgetwc(FILE *f) 52{ 53 wint_t c; 54 FLOCK(f); 55 c = __fgetwc_unlocked(f); 56 FUNLOCK(f); 57 return c; 58} 59 60weak_alias(__fgetwc_unlocked, fgetwc_unlocked); 61weak_alias(__fgetwc_unlocked, getwc_unlocked); 62