summaryrefslogtreecommitdiff
path: root/lib/libc/stdio/fread.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libc/stdio/fread.c')
-rw-r--r--lib/libc/stdio/fread.c17
1 files changed, 16 insertions, 1 deletions
diff --git a/lib/libc/stdio/fread.c b/lib/libc/stdio/fread.c
index 8a592f6d3f1..6e957623e1f 100644
--- a/lib/libc/stdio/fread.c
+++ b/lib/libc/stdio/fread.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: fread.c,v 1.12 2014/05/01 16:40:36 deraadt Exp $ */
+/* $OpenBSD: fread.c,v 1.13 2014/12/08 20:40:53 tedu Exp $ */
/*-
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
@@ -68,6 +68,21 @@ fread(void *buf, size_t size, size_t count, FILE *fp)
fp->_r = 0;
total = resid;
p = buf;
+
+ if ((fp->_flags & __SNBF) != 0) {
+ /*
+ * We know if we're unbuffered that our buffer is empty, so
+ * we can just read directly. This is much faster than the
+ * loop below which will perform a series of one byte reads.
+ */
+ while (resid > 0 && (r = (*fp->_read)(fp->_cookie, p, resid)) > 0) {
+ p += r;
+ resid -= r;
+ }
+ FUNLOCKFILE(fp);
+ return ((total - resid) / size);
+ }
+
while (resid > (r = fp->_r)) {
(void)memcpy((void *)p, (void *)fp->_p, (size_t)r);
fp->_p += r;