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.
This commit is contained in:
ache 2001-09-01 01:56:54 +00:00
parent 8f95e37de3
commit 5610a6ae63
5 changed files with 48 additions and 34 deletions

View File

@ -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,9 +211,16 @@ _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
@ -220,28 +228,29 @@ _fseeko(fp, offset, whence, ltest)
* 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;

View File

@ -75,28 +75,34 @@ off_t
ftello(fp)
register FILE *fp;
{
register off_t rv;
fpos_t rv;
int ret;
/* make sure stdio is set up */
if (!__sdidinit)
__sinit();
FLOCKFILE(fp);
rv = _ftello(fp);
ret = _ftello(fp, &rv);
FUNLOCKFILE(fp);
if (ret)
return (-1);
if (rv < 0) /* Unspecified value because of ungetc() at 0 */
rv = 0;
return (rv);
}
off_t
_ftello(fp)
int
_ftello(fp, offset)
register FILE *fp;
fpos_t *offset;
{
register fpos_t pos, spos;
size_t n;
if (fp->_seek == NULL) {
errno = ESPIPE; /* historic practice */
return (-1);
return (1);
}
/*
@ -110,7 +116,7 @@ _ftello(fp)
get_real_pos:
spos = pos = (*fp->_seek)(fp->_cookie, (fpos_t)0, SEEK_CUR);
if (pos == -1)
return (-1);
return (1);
}
if (fp->_flags & __SRD) {
/*
@ -118,16 +124,21 @@ _ftello(fp)
* those from ungetc) cause the position to be
* smaller than that in the underlying object.
*/
if ((pos -= fp->_r) < 0 ||
(HASUB(fp) && (pos -= fp->_ur) < 0)) {
fp->_p = fp->_bf._base;
fp->_r = 0;
if (HASUB(fp))
FREEUB(fp);
if ((pos -= (HASUB(fp) ? fp->_ur : fp->_r)) < 0) {
/* Lost position, resync. */
if (HASUB(fp)) {
fp->_extra->_up = fp->_bf._base;
fp->_ur = 0;
} else {
fp->_p = fp->_bf._base;
fp->_r = 0;
}
if (spos == -1)
goto get_real_pos;
pos = spos;
}
if (HASUB(fp))
pos -= fp->_r; /* Can be negative at this point. */
} else if ((fp->_flags & __SWR) && fp->_p != NULL) {
/*
* Writing. Any buffered characters cause the
@ -137,9 +148,10 @@ _ftello(fp)
n = fp->_p - fp->_bf._base;
if (pos > OFF_MAX - n) {
errno = EOVERFLOW;
return (-1);
return (1);
}
pos += n;
}
return (pos);
*offset = pos;
return (0);
}

View File

@ -46,8 +46,8 @@
* in particular, macros and private variables.
*/
extern off_t _ftello __P((FILE *));
extern int _fseeko __P((FILE *, off_t, int, int));
extern int _ftello __P((FILE *, fpos_t *));
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));

View File

@ -83,10 +83,7 @@ if the operation fails.
If the value of the argument
.Fa c
character equals
.Dv EOF
or current
.Fa stream
offset equals 0,
.Dv EOF ,
the operation will fail and the stream will remain unchanged.
.Sh SEE ALSO
.Xr fseek 3 ,

View File

@ -132,10 +132,6 @@ __ungetc(int c, FILE *fp)
}
fp->_flags |= __SRD;
}
if (!(fp->_flags & __SSTR) && _ftello(fp) == 0)
return (EOF);
c = (unsigned char)c;
/*