diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/libc/stdio/fseek.c | 91 | ||||
-rw-r--r-- | lib/libc/stdio/ftell.c | 32 | ||||
-rw-r--r-- | lib/libc/stdio/local.h | 1 |
3 files changed, 30 insertions, 94 deletions
diff --git a/lib/libc/stdio/fseek.c b/lib/libc/stdio/fseek.c index 4e3d5cc..7cf117a 100644 --- a/lib/libc/stdio/fseek.c +++ b/lib/libc/stdio/fseek.c @@ -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 @@ abspos: 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 @@ abspos: fp->_p += n; fp->_r -= n; } + fp->_flags &= ~__SEOF; return (0); /* diff --git a/lib/libc/stdio/ftell.c b/lib/libc/stdio/ftell.c index 33184c5..974b484 100644 --- a/lib/libc/stdio/ftell.c +++ b/lib/libc/stdio/ftell.c @@ -75,6 +75,18 @@ 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); } diff --git a/lib/libc/stdio/local.h b/lib/libc/stdio/local.h index 5c0d347..00ec2d8 100644 --- a/lib/libc/stdio/local.h +++ b/lib/libc/stdio/local.h @@ -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 *)); |