summaryrefslogtreecommitdiffstats
path: root/lib/libc
diff options
context:
space:
mode:
authorache <ache@FreeBSD.org>2016-09-05 01:57:32 +0000
committerache <ache@FreeBSD.org>2016-09-05 01:57:32 +0000
commit23cf012b280ed8f8274e25a82bf44492132b1419 (patch)
tree364acde762ec68fd48037f015ccda7d49712c939 /lib/libc
parent3d5d624919bed2dbb0c49b5fb0e538a47b69aca2 (diff)
downloadFreeBSD-src-23cf012b280ed8f8274e25a82bf44492132b1419.zip
FreeBSD-src-23cf012b280ed8f8274e25a82bf44492132b1419.tar.gz
MFC r305241
fgetwc(3) may set both __SEOF and __SERR at once (in case of incomplete sequence near EOF), so we can't just check for (wc == WEOF && !__sfeof(fp)) and must relay on __sferror(fp) with __SERR clearing/restoring.
Diffstat (limited to 'lib/libc')
-rw-r--r--lib/libc/stdio/fgetwln.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/lib/libc/stdio/fgetwln.c b/lib/libc/stdio/fgetwln.c
index 34a80a0..037657c 100644
--- a/lib/libc/stdio/fgetwln.c
+++ b/lib/libc/stdio/fgetwln.c
@@ -47,11 +47,16 @@ fgetwln_l(FILE * __restrict fp, size_t *lenp, locale_t locale)
{
wint_t wc;
size_t len;
+ int savserr;
+
FIX_LOCALE(locale);
FLOCKFILE(fp);
ORIENT(fp, 1);
+ savserr = fp->_flags & __SERR;
+ fp->_flags &= ~__SERR;
+
len = 0;
while ((wc = __fgetwc(fp, locale)) != WEOF) {
#define GROW 512
@@ -64,7 +69,12 @@ fgetwln_l(FILE * __restrict fp, size_t *lenp, locale_t locale)
if (wc == L'\n')
break;
}
- if (len == 0 || (wc == WEOF && !__sfeof(fp)))
+ /* fgetwc(3) may set both __SEOF and __SERR at once. */
+ if (__sferror(fp))
+ goto error;
+
+ fp->_flags |= savserr;
+ if (len == 0)
goto error;
FUNLOCKFILE(fp);
OpenPOWER on IntegriCloud