summaryrefslogtreecommitdiffstats
path: root/lib/libc/stdio/ftell.c
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/libc/stdio/ftell.c
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/libc/stdio/ftell.c')
-rw-r--r--lib/libc/stdio/ftell.c32
1 files changed, 22 insertions, 10 deletions
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);
}
OpenPOWER on IntegriCloud