diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/stdio/fgetwc.c | 28 | 
1 files changed, 14 insertions, 14 deletions
| diff --git a/src/stdio/fgetwc.c b/src/stdio/fgetwc.c index a00c1a86..07fb6d7c 100644 --- a/src/stdio/fgetwc.c +++ b/src/stdio/fgetwc.c @@ -5,36 +5,36 @@  static wint_t __fgetwc_unlocked_internal(FILE *f)  { -	mbstate_t st = { 0 };  	wchar_t wc;  	int c; -	unsigned char b;  	size_t l;  	/* Convert character from buffer if possible */  	if (f->rpos < f->rend) { -		l = mbrtowc(&wc, (void *)f->rpos, f->rend - f->rpos, &st); -		if (l+2 >= 2) { +		l = mbtowc(&wc, (void *)f->rpos, f->rend - f->rpos); +		if (l+1 >= 1) {  			f->rpos += l + !l; /* l==0 means 1 byte, null */  			return wc;  		} -		if (l == -1) { -			f->rpos++; -			return WEOF; -		} -		f->rpos = f->rend; -	} else l = -2; +	}  	/* Convert character byte-by-byte */ -	while (l == -2) { +	mbstate_t st = { 0 }; +	unsigned char b; +	int first = 1; +	do {  		b = c = getc_unlocked(f);  		if (c < 0) { -			if (!mbsinit(&st)) errno = EILSEQ; +			if (!first) errno = EILSEQ;  			return WEOF;  		}  		l = mbrtowc(&wc, (void *)&b, 1, &st); -		if (l == -1) return WEOF; -	} +		if (l == -1) { +			if (!first) ungetc(b, f); +			return WEOF; +		} +		first = 0; +	} while (l == -2);  	return wc;  } | 
