[klibc] stdio: don't cache the file pointer

Caching the file pointer is incorrect for append streams, and if we
have to make system calls for append streams we might as well not
bother maintaining the file pointer at all... the biggest win came
from the fact the ftell() could be inlined.

A fully optimized libc can maintain the cached pointer for non-append
streams, but for klibc, don't bother maintaining the file pointer at
all, and just let the kernel worry about that.

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
diff --git a/usr/include/stdio.h b/usr/include/stdio.h
index 0d4c7d8..f0e81e9 100644
--- a/usr/include/stdio.h
+++ b/usr/include/stdio.h
@@ -12,7 +12,6 @@
 #include <unistd.h>
 
 struct _IO_file {
-	off_t _IO_filepos;	/* File position */
 	int _IO_fileno;		/* Underlying file descriptor */
 	_Bool _IO_eof;		/* End of file flag */
 	_Bool _IO_error;	/* Error flag */
@@ -113,11 +112,6 @@
 	return _fwrite(__p, __s * __n, __f) / __s;
 }
 
-__extern_inline off_t ftell(FILE *__f)
-{
-	return __f->_IO_filepos;
-}
-
 __extern_inline int fileno(FILE *__f)
 {
 	return __f->_IO_fileno;
diff --git a/usr/klibc/stdio/fdopen.c b/usr/klibc/stdio/fdopen.c
index 2536eb7..a921b59 100644
--- a/usr/klibc/stdio/fdopen.c
+++ b/usr/klibc/stdio/fdopen.c
@@ -21,7 +21,6 @@
 	const size_t bufoffs =
 		(sizeof *f + 4*sizeof(void *) - 1) &
 		~(4*sizeof(void *) - 1);
-	off_t pos;
 
 	(void)mode;
 
@@ -31,8 +30,6 @@
 
 	f->data = f->buf = (char *)f + bufoffs;
 	f->pub._IO_fileno = fd;
-	pos = lseek(fd, 0, SEEK_CUR);
-	f->pub._IO_filepos = (pos >= 0) ? pos : 0;
 	f->bufsiz = BUFSIZ;
 	f->bufmode = isatty(fd) ? _IOLBF : _IOFBF;
 
diff --git a/usr/klibc/stdio/fgetc.c b/usr/klibc/stdio/fgetc.c
index 04d9ce0..a0e8650 100644
--- a/usr/klibc/stdio/fgetc.c
+++ b/usr/klibc/stdio/fgetc.c
@@ -11,7 +11,6 @@
 
 	if (__likely(f->ibytes)) {
 		f->ibytes--;
-		f->pub._IO_filepos++;
 		return (unsigned char) *f->data++;
 	} else {
 		return _fread(&ch, 1, file) == 1 ? ch : EOF;
diff --git a/usr/klibc/stdio/fread.c b/usr/klibc/stdio/fread.c
index caad20b..b099426 100644
--- a/usr/klibc/stdio/fread.c
+++ b/usr/klibc/stdio/fread.c
@@ -54,7 +54,6 @@
 				p += rv;
 				bytes += rv;
 				count -= rv;
-				f->pub._IO_filepos += rv;
 			} else {
 				f->ibytes = rv;
 				f->data = rdptr;
@@ -74,7 +73,6 @@
 			count -= nb;
 			f->data += nb;
 			f->ibytes -= nb;
-			f->pub._IO_filepos += nb;
 		}
 	}
 	return bytes;
diff --git a/usr/klibc/stdio/fseek.c b/usr/klibc/stdio/fseek.c
index d352aa0..adfcbeb 100644
--- a/usr/klibc/stdio/fseek.c
+++ b/usr/klibc/stdio/fseek.c
@@ -13,14 +13,11 @@
 		if (__fflush(f))
 			return -1;
 
-	if (whence == SEEK_CUR) {
-		where += f->pub._IO_filepos;
-		whence = SEEK_SET;
-	}
+	if (whence == SEEK_CUR)
+		where -= f->ibytes;
 
 	rv = lseek(f->pub._IO_fileno, where, whence);
 	if (__likely(rv != (off_t)-1)) {
-		f->pub._IO_filepos = rv;
 		f->pub._IO_eof = false;
 		f->ibytes = 0;
 		f->obytes = 0;
diff --git a/usr/klibc/stdio/ftell.c b/usr/klibc/stdio/ftell.c
index f3133d8..cb1202d 100644
--- a/usr/klibc/stdio/ftell.c
+++ b/usr/klibc/stdio/ftell.c
@@ -1,7 +1,12 @@
-#define __NO_STDIO_INLINES
 #include "stdioint.h"
 
-off_t ftell(FILE *f)
+off_t ftell(FILE *file)
 {
-	return f->_IO_filepos;
+	struct _IO_file_pvt *f = stdio_pvt(file);
+	off_t pos = lseek(f->pub._IO_fileno, 0, SEEK_CUR);
+
+	if (pos >= 0)
+		pos += (int)f->obytes - (int)f->ibytes;
+
+	return pos;
 }
diff --git a/usr/klibc/stdio/fwrite.c b/usr/klibc/stdio/fwrite.c
index 86eb3d4..d167257 100644
--- a/usr/klibc/stdio/fwrite.c
+++ b/usr/klibc/stdio/fwrite.c
@@ -38,7 +38,6 @@
 			p += rv;
 			bytes += rv;
 			count -= rv;
-			f->pub._IO_filepos += rv;
 		} else {
 			nb = f->bufsiz - f->obytes;
 			nb = (count < nb) ? count : nb;
@@ -48,7 +47,6 @@
 				f->obytes += nb;
 				count -= nb;
 				bytes += nb;
-				f->pub._IO_filepos += nb;
 			}
 		}
 	}