diff options
author | ache <ache@FreeBSD.org> | 2001-08-17 09:57:11 +0000 |
---|---|---|
committer | ache <ache@FreeBSD.org> | 2001-08-17 09:57:11 +0000 |
commit | ca91420dc83eb61f050e2c2e5c063ad0b8ab2b4c (patch) | |
tree | 1ac14d62b577338fdc2eef8fa860217334dddad7 /lib/libc/stdio/fseek.c | |
parent | 141c7ecefc74015b064137ab8e39f6582bec1697 (diff) | |
download | FreeBSD-src-ca91420dc83eb61f050e2c2e5c063ad0b8ab2b4c.zip FreeBSD-src-ca91420dc83eb61f050e2c2e5c063ad0b8ab2b4c.tar.gz |
fseek.c:
Resulting fseek() offset must fit in long, required by POSIX (pointed by bde),
so add LONG_MAX and final tests for it.
rewind.c:
1) add missing __sinit() as in fseek() it pretends to be.
2) use clearerr_unlocked() since we already lock stream before _fseeko()
3) don't zero errno at the end, it explicitely required by POSIX as the
only one method to test rewind() error condition.
4) don't clearerr() if error happens in _fseeko()
Diffstat (limited to 'lib/libc/stdio/fseek.c')
-rw-r--r-- | lib/libc/stdio/fseek.c | 28 |
1 files changed, 23 insertions, 5 deletions
diff --git a/lib/libc/stdio/fseek.c b/lib/libc/stdio/fseek.c index c357370..e0a1648 100644 --- a/lib/libc/stdio/fseek.c +++ b/lib/libc/stdio/fseek.c @@ -62,7 +62,16 @@ fseek(fp, offset, whence) long offset; int whence; { - return (fseeko(fp, offset, whence)); + int ret; + + /* make sure stdio is set up */ + if (!__sdidinit) + __sinit(); + + FLOCKFILE(fp); + ret = _fseeko(fp, (off_t)offset, whence, 1); + FUNLOCKFILE(fp); + return (ret); } int @@ -78,7 +87,7 @@ fseeko(fp, offset, whence) __sinit(); FLOCKFILE(fp); - ret = _fseeko(fp, offset, whence); + ret = _fseeko(fp, offset, whence, 0); FUNLOCKFILE(fp); return (ret); } @@ -88,10 +97,11 @@ fseeko(fp, offset, whence) * `Whence' must be one of the three SEEK_* macros. */ int -_fseeko(fp, offset, whence) +_fseeko(fp, offset, whence, ltest) FILE *fp; off_t offset; int whence; + int ltest; { register fpos_t (*seekfn) __P((void *, fpos_t, int)); fpos_t target, curoff; @@ -134,7 +144,8 @@ _fseeko(fp, offset, whence) curoff += fp->_p - fp->_bf._base; /* curoff always >= 0 */ - if (offset > 0 && curoff > OFF_MAX - offset) { + if (offset > 0 && + curoff > (ltest ? LONG_MAX : OFF_MAX) - offset) { errno = EOVERFLOW; return (EOF); } @@ -197,7 +208,8 @@ _fseeko(fp, offset, whence) if (_fstat(fp->_file, &st)) goto dumb; /* st.st_size always >= 0 */ - if (offset > 0 && st.st_size > OFF_MAX - offset) { + if (offset > 0 && + st.st_size > (ltest ? LONG_MAX : OFF_MAX) - offset) { errno = EOVERFLOW; return (EOF); } @@ -290,6 +302,12 @@ dumb: if (__sflush(fp) || (*seekfn)(fp->_cookie, (fpos_t)offset, whence) == POS_ERR) return (EOF); + /* POSIX require long type resulting offset for fseek() */ + if (ltest && fp->_offset != (long)fp->_offset) { + fp->_flags &= ~__SOFF; + errno = EOVERFLOW; + return (EOF); + } /* success: clear EOF indicator and discard ungetc() data */ if (HASUB(fp)) FREEUB(fp); |