summaryrefslogtreecommitdiffstats
path: root/lib/libc/stdio/fseek.c
diff options
context:
space:
mode:
authorache <ache@FreeBSD.org>2001-08-17 09:57:11 +0000
committerache <ache@FreeBSD.org>2001-08-17 09:57:11 +0000
commitca91420dc83eb61f050e2c2e5c063ad0b8ab2b4c (patch)
tree1ac14d62b577338fdc2eef8fa860217334dddad7 /lib/libc/stdio/fseek.c
parent141c7ecefc74015b064137ab8e39f6582bec1697 (diff)
downloadFreeBSD-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.c28
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);
OpenPOWER on IntegriCloud