• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include "stdio_impl.h"
2 #include "locale_impl.h"
3 #include <wchar.h>
4 #include <errno.h>
5 
__fgetwc_unlocked_internal(FILE * f)6 static 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 
__fgetwc_unlocked(FILE * f)48 wint_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 
fgetwc(FILE * f)58 wint_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 
67 weak_alias(__fgetwc_unlocked, fgetwc_unlocked);
68 weak_alias(__fgetwc_unlocked, getwc_unlocked);
69