summaryrefslogtreecommitdiff
path: root/src/stdio/ftell.c
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2018-09-16 13:46:46 -0400
committerRich Felker <dalias@aerifal.cx>2018-09-16 14:37:22 -0400
commit849e7603e9004fd292a93df64dd3524025f2987a (patch)
tree4a8e8b168be59045998b430f7654464025affeaf /src/stdio/ftell.c
parent5cd309f0cc3c92f3fabbaa499652a8329137c4de (diff)
downloadmusl-849e7603e9004fd292a93df64dd3524025f2987a.tar.gz
fix null pointer subtraction and comparison in stdio
morally, for null pointers a and b, a-b, a<b, and a>b should all be defined as 0; however, C does not define any of them. the stdio implementation makes heavy use of such pointer comparison and subtraction for buffer logic, and also uses null pos/base/end pointers to indicate that the FILE is not in the corresponding (read or write) mode ready for accesses through the buffer. all of the comparisons are fixed trivially by using != in place of the relational operators, since the opposite relation (e.g. pos>end) is logically impossible. the subtractions have been reviewed to check that they are conditional the stream being in the appropriate reading- or writing-through-buffer mode, with checks added where needed. in fgets and getdelim, the checks added should improve performance for unbuffered streams by avoiding a do-nothing call to memchr, and should be negligible for buffered streams.
Diffstat (limited to 'src/stdio/ftell.c')
-rw-r--r--src/stdio/ftell.c8
1 files changed, 6 insertions, 2 deletions
diff --git a/src/stdio/ftell.c b/src/stdio/ftell.c
index 5ca41654..1a2afbbc 100644
--- a/src/stdio/ftell.c
+++ b/src/stdio/ftell.c
@@ -5,12 +5,16 @@
off_t __ftello_unlocked(FILE *f)
{
off_t pos = f->seek(f, 0,
- (f->flags & F_APP) && f->wpos > f->wbase
+ (f->flags & F_APP) && f->wpos != f->wbase
? SEEK_END : SEEK_CUR);
if (pos < 0) return pos;
/* Adjust for data in buffer. */
- return pos - (f->rend - f->rpos) + (f->wpos - f->wbase);
+ if (f->rend)
+ pos += f->rpos - f->rend;
+ else if (f->wbase)
+ pos += f->wpos - f->wbase;
+ return pos;
}
off_t __ftello(FILE *f)