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 wchar_t wc; 9 int c; 10 size_t l; 11 12 /* Convert character from buffer if possible */ 13 if (f->rpos != f->rend) { 14 l = mbtowc(&wc, (void *)f->rpos, f->rend - f->rpos); 15 if (l+1 >= 1) { 16 f->rpos += l + !l; /* l==0 means 1 byte, null */ 17 return wc; 18 } 19 } 20 21 /* Convert character byte-by-byte */ 22 mbstate_t st = { 0 }; 23 unsigned char b; 24 int first = 1; 25 do { 26 b = c = getc_unlocked(f); 27 if (c < 0) { 28 if (!first) { 29 f->flags |= F_ERR; 30 errno = EILSEQ; 31 } 32 return WEOF; 33 } 34 l = mbrtowc(&wc, (void *)&b, 1, &st); 35 if (l == -1) { 36 if (!first) { 37 f->flags |= F_ERR; 38 ungetc(b, f); 39 } 40 return WEOF; 41 } 42 first = 0; 43 } while (l == -2); 44 45 return wc; 46} 47 48wint_t __fgetwc_unlocked(FILE *f) 49{ 50 locale_t *ploc = &CURRENT_LOCALE, loc = *ploc; 51 if (f->mode <= 0) fwide(f, 1); 52 *ploc = f->locale; 53 wchar_t wc = __fgetwc_unlocked_internal(f); 54 *ploc = loc; 55 return wc; 56} 57 58wint_t fgetwc(FILE *f) 59{ 60 wint_t c; 61 FLOCK(f); 62 c = __fgetwc_unlocked(f); 63 FUNLOCK(f); 64 return c; 65} 66 67weak_alias(__fgetwc_unlocked, fgetwc_unlocked); 68weak_alias(__fgetwc_unlocked, getwc_unlocked); 69