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()
This commit is contained in:
parent
fb9d17b07b
commit
71b5a4326d
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=81817
@ -185,7 +185,11 @@ The resulting file-position
|
||||
indicator would be set to a negative value.
|
||||
.It Bq Er EOVERFLOW
|
||||
The resulting file offset would be a value which
|
||||
cannot be represented correctly in an object of type requested.
|
||||
cannot be represented correctly in an object of type off_t
|
||||
for
|
||||
.Fn fseeko
|
||||
or long for
|
||||
.Fn fseek .
|
||||
.El
|
||||
.Pp
|
||||
The functions
|
||||
|
@ -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 @@ _fseeko(fp, offset, whence)
|
||||
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);
|
||||
|
@ -46,7 +46,7 @@
|
||||
* in particular, macros and private variables.
|
||||
*/
|
||||
|
||||
extern int _fseeko __P((FILE *, off_t, int));
|
||||
extern int _fseeko __P((FILE *, off_t, int, int));
|
||||
extern int __fflush __P((FILE *fp));
|
||||
extern int __sflush __P((FILE *));
|
||||
extern FILE *__sfp __P((void));
|
||||
|
@ -52,9 +52,13 @@ static const char rcsid[] =
|
||||
void
|
||||
rewind(FILE *fp)
|
||||
{
|
||||
/* make sure stdio is set up */
|
||||
if (!__sdidinit)
|
||||
__sinit();
|
||||
|
||||
FLOCKFILE(fp);
|
||||
(void) _fseeko(fp, (off_t)0, SEEK_SET);
|
||||
clearerr(fp);
|
||||
if (_fseeko(fp, (off_t)0, SEEK_SET, 1) == 0)
|
||||
clearerr_unlocked(fp);
|
||||
FUNLOCKFILE(fp);
|
||||
errno = 0; /* not required, but seems reasonable */
|
||||
/* errno required by POSIX to sense error, don't zero it here */
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user