diff options
author | ache <ache@FreeBSD.org> | 2016-08-27 11:07:57 +0000 |
---|---|---|
committer | ache <ache@FreeBSD.org> | 2016-08-27 11:07:57 +0000 |
commit | 151bfb59482950c55b935a404df11b9d3961fb6c (patch) | |
tree | 0f9b8d4be1f5b5dd92e48f35a3d39b5f8f2ccdb9 /lib/libc/stdio | |
parent | c75c3e9c541aa8bba4dedbbdd694bcb9aafd5e81 (diff) | |
download | FreeBSD-src-151bfb59482950c55b935a404df11b9d3961fb6c.zip FreeBSD-src-151bfb59482950c55b935a404df11b9d3961fb6c.tar.gz |
MFC r304607,r304641,r304819,r304811
1) Don't forget to set __SERR on __slbexpand() error.
2) Remove "Fast path" from fgetwc()/fputwc() since it can't detect
encoding errors and ignores them all.
One of affected encoding example: US-ASCII
3) Original fgetln() from 44lite return success for line tail errors,
i.e. partial line, but set __SERR and errno in the same time, which
is inconsistent.
Now both OpenBSD and NetBSD return failure, i.e. no line and set error
indicators for such case, so make our fgetln() and fgetwln()
(as its wide version) compatible with the rest of *BSD.
PR: 212033
Diffstat (limited to 'lib/libc/stdio')
-rw-r--r-- | lib/libc/stdio/fgetln.c | 7 | ||||
-rw-r--r-- | lib/libc/stdio/fgetwc.c | 13 | ||||
-rw-r--r-- | lib/libc/stdio/fgetwln.c | 7 | ||||
-rw-r--r-- | lib/libc/stdio/fputwc.c | 16 |
4 files changed, 15 insertions, 28 deletions
diff --git a/lib/libc/stdio/fgetln.c b/lib/libc/stdio/fgetln.c index 1509bc8..c8e30ee 100644 --- a/lib/libc/stdio/fgetln.c +++ b/lib/libc/stdio/fgetln.c @@ -139,8 +139,11 @@ fgetln(FILE *fp, size_t *lenp) (void)memcpy((void *)(fp->_lb._base + off), (void *)fp->_p, len - off); off = len; - if (__srefill(fp)) - break; /* EOF or error: return partial line */ + if (__srefill(fp)) { + if (__sfeof(fp)) + break; + goto error; + } if ((p = memchr((void *)fp->_p, '\n', (size_t)fp->_r)) == NULL) continue; diff --git a/lib/libc/stdio/fgetwc.c b/lib/libc/stdio/fgetwc.c index 52bc988..cf649fd 100644 --- a/lib/libc/stdio/fgetwc.c +++ b/lib/libc/stdio/fgetwc.c @@ -79,18 +79,9 @@ __fgetwc_mbs(FILE *fp, mbstate_t *mbs, int *nread, locale_t locale) size_t nconv; struct xlocale_ctype *l = XLOCALE_CTYPE(locale); - if (fp->_r <= 0 && __srefill(fp)) { - *nread = 0; - return (WEOF); - } - if (MB_CUR_MAX == 1) { - /* Fast path for single-byte encodings. */ - wc = *fp->_p++; - fp->_r--; - *nread = 1; - return (wc); - } *nread = 0; + if (fp->_r <= 0 && __srefill(fp)) + return (WEOF); do { nconv = l->__mbrtowc(&wc, fp->_p, fp->_r, mbs); if (nconv == (size_t)-1) diff --git a/lib/libc/stdio/fgetwln.c b/lib/libc/stdio/fgetwln.c index 8439496..34a80a0 100644 --- a/lib/libc/stdio/fgetwln.c +++ b/lib/libc/stdio/fgetwln.c @@ -56,13 +56,15 @@ fgetwln_l(FILE * __restrict fp, size_t *lenp, locale_t locale) while ((wc = __fgetwc(fp, locale)) != WEOF) { #define GROW 512 if (len * sizeof(wchar_t) >= fp->_lb._size && - __slbexpand(fp, (len + GROW) * sizeof(wchar_t))) + __slbexpand(fp, (len + GROW) * sizeof(wchar_t))) { + fp->_flags |= __SERR; goto error; + } *((wchar_t *)fp->_lb._base + len++) = wc; if (wc == L'\n') break; } - if (len == 0) + if (len == 0 || (wc == WEOF && !__sfeof(fp))) goto error; FUNLOCKFILE(fp); @@ -74,6 +76,7 @@ error: *lenp = 0; return (NULL); } + wchar_t * fgetwln(FILE * __restrict fp, size_t *lenp) { diff --git a/lib/libc/stdio/fputwc.c b/lib/libc/stdio/fputwc.c index 7b05d4a..7f0c910 100644 --- a/lib/libc/stdio/fputwc.c +++ b/lib/libc/stdio/fputwc.c @@ -53,19 +53,9 @@ __fputwc(wchar_t wc, FILE *fp, locale_t locale) size_t i, len; struct xlocale_ctype *l = XLOCALE_CTYPE(locale); - if (MB_CUR_MAX == 1 && wc > 0 && wc <= UCHAR_MAX) { - /* - * Assume single-byte locale with no special encoding. - * A more careful test would be to check - * _CurrentRuneLocale->encoding. - */ - *buf = (unsigned char)wc; - len = 1; - } else { - if ((len = l->__wcrtomb(buf, wc, &fp->_mbstate)) == (size_t)-1) { - fp->_flags |= __SERR; - return (WEOF); - } + if ((len = l->__wcrtomb(buf, wc, &fp->_mbstate)) == (size_t)-1) { + fp->_flags |= __SERR; + return (WEOF); } for (i = 0; i < len; i++) |