diff options
| author | Andrey A. Chernov <ache@FreeBSD.org> | 2001-08-17 09:57:11 +0000 | 
|---|---|---|
| committer | Andrey A. Chernov <ache@FreeBSD.org> | 2001-08-17 09:57:11 +0000 | 
| commit | 71b5a4326ddbfff4f2f249acea228dc5e642dd62 (patch) | |
| tree | 1ac14d62b577338fdc2eef8fa860217334dddad7 | |
| parent | fb9d17b07bebc5bd615e0ec8ecf9102e183437dd (diff) | |
Notes
| -rw-r--r-- | lib/libc/stdio/fseek.3 | 6 | ||||
| -rw-r--r-- | lib/libc/stdio/fseek.c | 28 | ||||
| -rw-r--r-- | lib/libc/stdio/local.h | 2 | ||||
| -rw-r--r-- | lib/libc/stdio/rewind.c | 10 | 
4 files changed, 36 insertions, 10 deletions
| diff --git a/lib/libc/stdio/fseek.3 b/lib/libc/stdio/fseek.3 index b37aa176df1f..1b5d39725965 100644 --- a/lib/libc/stdio/fseek.3 +++ b/lib/libc/stdio/fseek.3 @@ -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 diff --git a/lib/libc/stdio/fseek.c b/lib/libc/stdio/fseek.c index c357370d917c..e0a1648a550e 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); diff --git a/lib/libc/stdio/local.h b/lib/libc/stdio/local.h index 06fecc993df8..5c0d347a417b 100644 --- a/lib/libc/stdio/local.h +++ b/lib/libc/stdio/local.h @@ -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)); diff --git a/lib/libc/stdio/rewind.c b/lib/libc/stdio/rewind.c index c4de2c14e40b..af9232a7b17f 100644 --- a/lib/libc/stdio/rewind.c +++ b/lib/libc/stdio/rewind.c @@ -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 */  } | 
