summaryrefslogtreecommitdiffstats
path: root/lib/libc/stdio/ftell.c
diff options
context:
space:
mode:
authorache <ache@FreeBSD.org>2001-09-01 01:56:54 +0000
committerache <ache@FreeBSD.org>2001-09-01 01:56:54 +0000
commit5610a6ae63a163468769d8b1400a386115b53ddf (patch)
tree7df1c1e8cadd1748528a154d73547f9a81702dae /lib/libc/stdio/ftell.c
parent8f95e37de3db8c34682949479172b82e88dbacc5 (diff)
downloadFreeBSD-src-5610a6ae63a163468769d8b1400a386115b53ddf.zip
FreeBSD-src-5610a6ae63a163468769d8b1400a386115b53ddf.tar.gz
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.
Diffstat (limited to 'lib/libc/stdio/ftell.c')
-rw-r--r--lib/libc/stdio/ftell.c40
1 files changed, 26 insertions, 14 deletions
diff --git a/lib/libc/stdio/ftell.c b/lib/libc/stdio/ftell.c
index 61cd27c..a0fd175 100644
--- a/lib/libc/stdio/ftell.c
+++ b/lib/libc/stdio/ftell.c
@@ -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 @@ get_real_pos:
* 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 @@ get_real_pos:
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);
}
OpenPOWER on IntegriCloud