The same big piece of ftell code repeated in 3 places. Simplify things moving
it into one subfunction instead. Try to use real offset in strange cases.
This commit is contained in:
parent
05c03ed9b8
commit
2ff678f5bb
@ -104,7 +104,7 @@ _fseeko(fp, offset, whence, ltest)
|
||||
int ltest;
|
||||
{
|
||||
register fpos_t (*seekfn) __P((void *, fpos_t, int));
|
||||
fpos_t target, curoff, spos;
|
||||
fpos_t target, curoff;
|
||||
size_t n;
|
||||
struct stat st;
|
||||
int havepos;
|
||||
@ -126,53 +126,11 @@ _fseeko(fp, offset, whence, ltest)
|
||||
case SEEK_CUR:
|
||||
/*
|
||||
* In order to seek relative to the current stream offset,
|
||||
* we have to first find the current stream offset a la
|
||||
* we have to first find the current stream offset via
|
||||
* ftell (see ftell for details).
|
||||
*/
|
||||
if (fp->_flags & __SOFF)
|
||||
curoff = fp->_offset;
|
||||
else {
|
||||
curoff = (*seekfn)(fp->_cookie, (fpos_t)0, SEEK_CUR);
|
||||
if (curoff == -1)
|
||||
return (-1);
|
||||
}
|
||||
if (fp->_flags & __SRD) {
|
||||
spos = curoff;
|
||||
curoff -= fp->_r;
|
||||
if (curoff < 0) {
|
||||
if (HASUB(fp)) {
|
||||
fp->_p -= curoff;
|
||||
fp->_r += curoff;
|
||||
curoff = 0;
|
||||
} else {
|
||||
fp->_p = fp->_bf._base;
|
||||
fp->_r = 0;
|
||||
curoff = spos;
|
||||
}
|
||||
}
|
||||
if (HASUB(fp)) {
|
||||
curoff -= fp->_ur;
|
||||
if (curoff < 0) {
|
||||
if (-curoff <= fp->_r) {
|
||||
fp->_p -= curoff;
|
||||
fp->_r += curoff;
|
||||
curoff = 0;
|
||||
} else {
|
||||
fp->_p = fp->_bf._base;
|
||||
fp->_r = 0;
|
||||
FREEUB(fp);
|
||||
curoff = spos;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if ((fp->_flags & __SWR) && fp->_p != NULL) {
|
||||
n = fp->_p - fp->_bf._base;
|
||||
if (curoff > OFF_MAX - n) {
|
||||
errno = EOVERFLOW;
|
||||
return (-1);
|
||||
}
|
||||
curoff += n;
|
||||
}
|
||||
if ((curoff = _ftello(fp)) == -1)
|
||||
return (-1);
|
||||
if (offset > 0 && curoff > OFF_MAX - offset) {
|
||||
errno = EOVERFLOW;
|
||||
return (-1);
|
||||
@ -252,43 +210,8 @@ _fseeko(fp, offset, whence, ltest)
|
||||
}
|
||||
}
|
||||
|
||||
if (!havepos) {
|
||||
if (fp->_flags & __SOFF)
|
||||
curoff = fp->_offset;
|
||||
else {
|
||||
curoff = (*seekfn)(fp->_cookie, (fpos_t)0, SEEK_CUR);
|
||||
if (curoff == POS_ERR)
|
||||
goto dumb;
|
||||
}
|
||||
spos = curoff;
|
||||
curoff -= fp->_r;
|
||||
if (curoff < 0) {
|
||||
if (HASUB(fp)) {
|
||||
fp->_p -= curoff;
|
||||
fp->_r += curoff;
|
||||
curoff = 0;
|
||||
} else {
|
||||
fp->_p = fp->_bf._base;
|
||||
fp->_r = 0;
|
||||
curoff = spos;
|
||||
}
|
||||
}
|
||||
if (HASUB(fp)) {
|
||||
curoff -= fp->_ur;
|
||||
if (curoff < 0) {
|
||||
if (-curoff <= fp->_r) {
|
||||
fp->_p -= curoff;
|
||||
fp->_r += curoff;
|
||||
curoff = 0;
|
||||
} else {
|
||||
fp->_p = fp->_bf._base;
|
||||
fp->_r = 0;
|
||||
FREEUB(fp);
|
||||
curoff = spos;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!havepos && (curoff = _ftello(fp)) == -1)
|
||||
goto dumb;
|
||||
|
||||
/*
|
||||
* Compute the number of bytes in the input buffer (pretending
|
||||
@ -346,7 +269,6 @@ _fseeko(fp, offset, whence, ltest)
|
||||
fp->_p = fp->_bf._base;
|
||||
if (HASUB(fp))
|
||||
FREEUB(fp);
|
||||
fp->_flags &= ~__SEOF;
|
||||
n = target - curoff;
|
||||
if (n) {
|
||||
if (__srefill(fp) || fp->_r < n)
|
||||
@ -354,6 +276,7 @@ _fseeko(fp, offset, whence, ltest)
|
||||
fp->_p += n;
|
||||
fp->_r -= n;
|
||||
}
|
||||
fp->_flags &= ~__SEOF;
|
||||
return (0);
|
||||
|
||||
/*
|
||||
|
@ -74,6 +74,18 @@ ftell(fp)
|
||||
off_t
|
||||
ftello(fp)
|
||||
register FILE *fp;
|
||||
{
|
||||
register off_t rv;
|
||||
|
||||
FLOCKFILE(fp);
|
||||
rv = _ftello(fp);
|
||||
FUNLOCKFILE(fp);
|
||||
return (rv);
|
||||
}
|
||||
|
||||
off_t
|
||||
_ftello(fp)
|
||||
register FILE *fp;
|
||||
{
|
||||
register fpos_t pos, spos;
|
||||
size_t n;
|
||||
@ -83,19 +95,18 @@ ftello(fp)
|
||||
return (-1);
|
||||
}
|
||||
|
||||
FLOCKFILE(fp);
|
||||
/*
|
||||
* Find offset of underlying I/O object, then
|
||||
* adjust for buffered bytes.
|
||||
*/
|
||||
if (fp->_flags & __SOFF)
|
||||
if (fp->_flags & __SOFF) {
|
||||
pos = fp->_offset;
|
||||
else {
|
||||
pos = (*fp->_seek)(fp->_cookie, (fpos_t)0, SEEK_CUR);
|
||||
if (pos == -1) {
|
||||
FUNLOCKFILE(fp);
|
||||
spos = -1;
|
||||
} else {
|
||||
get_real_pos:
|
||||
spos = pos = (*fp->_seek)(fp->_cookie, (fpos_t)0, SEEK_CUR);
|
||||
if (pos == -1)
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
if (fp->_flags & __SRD) {
|
||||
/*
|
||||
@ -103,7 +114,6 @@ ftello(fp)
|
||||
* those from ungetc) cause the position to be
|
||||
* smaller than that in the underlying object.
|
||||
*/
|
||||
spos = pos;
|
||||
pos -= fp->_r;
|
||||
if (pos < 0) {
|
||||
if (HASUB(fp)) {
|
||||
@ -111,6 +121,8 @@ ftello(fp)
|
||||
fp->_r += pos;
|
||||
pos = 0;
|
||||
} else {
|
||||
if (spos == -1)
|
||||
goto get_real_pos;
|
||||
fp->_p = fp->_bf._base;
|
||||
fp->_r = 0;
|
||||
pos = spos;
|
||||
@ -124,6 +136,8 @@ ftello(fp)
|
||||
fp->_r += pos;
|
||||
pos = 0;
|
||||
} else {
|
||||
if (spos == -1)
|
||||
goto get_real_pos;
|
||||
fp->_p = fp->_bf._base;
|
||||
fp->_r = 0;
|
||||
FREEUB(fp);
|
||||
@ -139,12 +153,10 @@ ftello(fp)
|
||||
*/
|
||||
n = fp->_p - fp->_bf._base;
|
||||
if (pos > OFF_MAX - n) {
|
||||
FUNLOCKFILE(fp);
|
||||
errno = EOVERFLOW;
|
||||
return (-1);
|
||||
}
|
||||
pos += n;
|
||||
}
|
||||
FUNLOCKFILE(fp);
|
||||
return (pos);
|
||||
}
|
||||
|
@ -46,6 +46,7 @@
|
||||
* in particular, macros and private variables.
|
||||
*/
|
||||
|
||||
extern off_t _ftello __P((FILE *));
|
||||
extern int _fseeko __P((FILE *, off_t, int, int));
|
||||
extern int __fflush __P((FILE *fp));
|
||||
extern int __sflush __P((FILE *));
|
||||
|
Loading…
Reference in New Issue
Block a user