aboutsummaryrefslogtreecommitdiff
path: root/lib/libc/stdio/stdio.c
diff options
context:
space:
mode:
authorAndrey A. Chernov <ache@FreeBSD.org>2001-08-15 02:07:47 +0000
committerAndrey A. Chernov <ache@FreeBSD.org>2001-08-15 02:07:47 +0000
commitd9e3eff33a03bcb668a9c9924443bf3b2d18bd15 (patch)
treec651de630103d0b82ee727fa499a87af0697e6f6 /lib/libc/stdio/stdio.c
parentba8140a6f656845b1445c969430263a01670f9d0 (diff)
downloadsrc-d9e3eff33a03bcb668a9c9924443bf3b2d18bd15.tar.gz
src-d9e3eff33a03bcb668a9c9924443bf3b2d18bd15.zip
1) Disallow negative seek as POSIX require for fseek{o} (but not for lseek):
"[EINVAL] ... The resulting file-position indicator would be set to a negative value." Moreover, in real life negative seek in stdio cause EOF indicator cleared and not set again forever even if EOF returned. 2) Catch few possible off_t overflows. Reviewed by: arch discussion
Notes
Notes: svn path=/head/; revision=81666
Diffstat (limited to 'lib/libc/stdio/stdio.c')
-rw-r--r--lib/libc/stdio/stdio.c19
1 files changed, 17 insertions, 2 deletions
diff --git a/lib/libc/stdio/stdio.c b/lib/libc/stdio/stdio.c
index 57be5bb42140..58fafcbc170f 100644
--- a/lib/libc/stdio/stdio.c
+++ b/lib/libc/stdio/stdio.c
@@ -43,6 +43,7 @@ static const char rcsid[] =
#endif /* LIBC_SCCS and not lint */
#include "namespace.h"
+#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
@@ -94,10 +95,24 @@ __sseek(cookie, offset, whence)
register FILE *fp = cookie;
register off_t ret;
+ /*
+ * Disallow negative seeks per POSIX.
+ * It is needed here to help upper level caller
+ * (fseek) in the cases it can't detect.
+ */
+ if (whence == SEEK_SET && (off_t)offset < 0) {
+ errno = EINVAL;
+ return (-1);
+ }
ret = lseek(fp->_file, (off_t)offset, whence);
- if (ret == -1)
+ if (ret < 0) {
+ if (ret != -1) {
+ /* Resulting seek is negative! */
+ ret = -1;
+ errno = EINVAL;
+ }
fp->_flags &= ~__SOFF;
- else {
+ } else {
fp->_flags |= __SOFF;
fp->_offset = ret;
}