summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorschwarze <schwarze@openbsd.org>2016-08-25 19:21:33 +0000
committerschwarze <schwarze@openbsd.org>2016-08-25 19:21:33 +0000
commita29ed0e9c9de7c24a3629c01cf943e9e9838bab2 (patch)
tree3b332231236dca4fc199292794f067aab829c6ec
parentFix sosplice tests on 32 bit systems by putting the correct number (diff)
downloadwireguard-openbsd-a29ed0e9c9de7c24a3629c01cf943e9e9838bab2.tar.xz
wireguard-openbsd-a29ed0e9c9de7c24a3629c01cf943e9e9838bab2.zip
After read errors, fgetln(3) sometimes succeeded (returning non-NULL)
and failed (setting errno and ferror(3)) both at the same time. That's a bad idea in general, and here in particular since returning partial lines was neither reliable (sometimes, you got NULL anyway) nor predictable (almost always, the line would be truncated long before the actual read error). Instead, on read failure, fail properly and always return NULL. Issue found in a discussion with Andrey Chernov <ache at freebsd dot org> who finally agreed to move FreeBSD into the same direction. The fix is joint work with and OK by millert@.
-rw-r--r--lib/libc/stdio/fgetln.c9
1 files changed, 6 insertions, 3 deletions
diff --git a/lib/libc/stdio/fgetln.c b/lib/libc/stdio/fgetln.c
index ae2eb10f96c..a5ea1b3207e 100644
--- a/lib/libc/stdio/fgetln.c
+++ b/lib/libc/stdio/fgetln.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: fgetln.c,v 1.14 2015/08/31 02:53:57 guenther Exp $ */
+/* $OpenBSD: fgetln.c,v 1.15 2016/08/25 19:21:33 schwarze Exp $ */
/*-
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
@@ -115,8 +115,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 (fp->_flags & __SEOF)
+ break;
+ goto error;
+ }
if ((p = memchr((void *)fp->_p, '\n', fp->_r)) == NULL)
continue;