summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorache <ache@FreeBSD.org>2001-08-31 18:23:29 +0000
committerache <ache@FreeBSD.org>2001-08-31 18:23:29 +0000
commit2362fc36bc1d2beae0027a778eeca43c5f18bc8d (patch)
treeef0edbd2131d5fbfeb3556a582d2491b8a11f007 /lib
parent85477cf711c667771f03f0ccd26176800e8e751d (diff)
downloadFreeBSD-src-2362fc36bc1d2beae0027a778eeca43c5f18bc8d.zip
FreeBSD-src-2362fc36bc1d2beae0027a778eeca43c5f18bc8d.tar.gz
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.
Diffstat (limited to 'lib')
-rw-r--r--lib/libc/stdio/fseek.c91
-rw-r--r--lib/libc/stdio/ftell.c32
-rw-r--r--lib/libc/stdio/local.h1
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 *));
OpenPOWER on IntegriCloud