summaryrefslogtreecommitdiffstats
path: root/lib/libc/stdio/fseek.c
diff options
context:
space:
mode:
authorache <ache@FreeBSD.org>2001-09-01 01:56:54 +0000
committerache <ache@FreeBSD.org>2001-09-01 01:56:54 +0000
commit5610a6ae63a163468769d8b1400a386115b53ddf (patch)
tree7df1c1e8cadd1748528a154d73547f9a81702dae /lib/libc/stdio/fseek.c
parent8f95e37de3db8c34682949479172b82e88dbacc5 (diff)
downloadFreeBSD-src-5610a6ae63a163468769d8b1400a386115b53ddf.zip
FreeBSD-src-5610a6ae63a163468769d8b1400a386115b53ddf.tar.gz
Back out disabling ungetc() at 0, use different solution:
keep negative offset internally, but return 0 externally in ftell*() I.e. use 0 now as 'unspecified value' per POSIX ungetc() description.
Diffstat (limited to 'lib/libc/stdio/fseek.c')
-rw-r--r--lib/libc/stdio/fseek.c29
1 files changed, 19 insertions, 10 deletions
diff --git a/lib/libc/stdio/fseek.c b/lib/libc/stdio/fseek.c
index 7cf117a..a3c80c1 100644
--- a/lib/libc/stdio/fseek.c
+++ b/lib/libc/stdio/fseek.c
@@ -129,9 +129,10 @@ _fseeko(fp, offset, whence, ltest)
* we have to first find the current stream offset via
* ftell (see ftell for details).
*/
- if ((curoff = _ftello(fp)) == -1)
+ if (_ftello(fp, &curoff))
return (-1);
- if (offset > 0 && curoff > OFF_MAX - offset) {
+ if ((offset > 0 && curoff > OFF_MAX - offset) ||
+ (offset < 0 && curoff < OFF_MIN - offset)) {
errno = EOVERFLOW;
return (-1);
}
@@ -210,38 +211,46 @@ _fseeko(fp, offset, whence, ltest)
}
}
- if (!havepos && (curoff = _ftello(fp)) == -1)
+ if (!havepos && _ftello(fp, &curoff))
goto dumb;
/*
+ * (If the buffer was modified, we have to
+ * skip this; see fgetln.c.)
+ */
+ if (fp->_flags & __SMOD)
+ goto abspos;
+
+ /*
* Compute the number of bytes in the input buffer (pretending
* that any ungetc() input has been discarded). Adjust current
* offset backwards by this count so that it represents the
* file offset for the first byte in the current input buffer.
*/
if (HASUB(fp)) {
- if (curoff > OFF_MAX - fp->_r)
+ if (curoff > 0 && fp->_r > OFF_MAX - curoff)
goto abspos;
curoff += fp->_r; /* kill off ungetc */
n = fp->_extra->_up - fp->_bf._base;
+ if (curoff < 0 && -((off_t)n) < OFF_MIN - curoff)
+ goto abspos;
curoff -= n;
n += fp->_ur;
} else {
n = fp->_p - fp->_bf._base;
+ if (curoff < 0 && -((off_t)n) < OFF_MIN - curoff)
+ goto abspos;
curoff -= n;
n += fp->_r;
}
- /* curoff can be negative at this point. */
/*
* If the target offset is within the current buffer,
* simply adjust the pointers, clear EOF, undo ungetc(),
- * and return. (If the buffer was modified, we have to
- * skip this; see fgetln.c.)
+ * and return.
*/
- if ((fp->_flags & __SMOD) == 0 &&
- target >= curoff &&
- (curoff <= 0 || curoff <= OFF_MAX - n) &&
+ if (target >= curoff &&
+ (curoff <= 0 || n <= OFF_MAX - curoff) &&
target < curoff + n) {
size_t o = target - curoff;
OpenPOWER on IntegriCloud