From 8911c0223773b6fff80d376aa9103f58bf2475f8 Mon Sep 17 00:00:00 2001 From: Sam Hocevar Date: Thu, 28 Dec 2006 17:48:05 +0000 Subject: [PATCH] * Fixed a partial read data loss bug in the fread implementation. * Cosmetic fixes. --- src/load-fd.c | 14 +++----------- src/load-stream.c | 33 ++++++++++++++++++++++----------- 2 files changed, 25 insertions(+), 22 deletions(-) diff --git a/src/load-fd.c b/src/load-fd.c index 47d83c4..ccc89c5 100644 --- a/src/load-fd.c +++ b/src/load-fd.c @@ -118,10 +118,7 @@ ssize_t read(int fd, void *buf, size_t count) if(!_zzuf_ready) LOADSYM(read); ret = read_orig(fd, buf, count); - if(!_zzuf_ready) - return ret; - - if(!zfd_ismanaged(fd)) + if(!_zzuf_ready || !zfd_ismanaged(fd)) return ret; debug("read(%i, %p, %li) = %i", fd, buf, (long int)count, ret); @@ -143,9 +140,7 @@ ssize_t read(int fd, void *buf, size_t count) if(!_zzuf_ready) \ LOADSYM(fn); \ ret = ORIG(fn)(fd, offset, whence); \ - if(!_zzuf_ready) \ - return ret; \ - if(!zfd_ismanaged(fd)) \ + if(!_zzuf_ready || !zfd_ismanaged(fd)) \ return ret; \ debug(STR(fn)"(%i, %lli, %i) = %lli", \ fd, (long long int)offset, whence, (long long int)ret); \ @@ -174,10 +169,7 @@ int close(int fd) if(!_zzuf_ready) LOADSYM(close); ret = close_orig(fd); - if(!_zzuf_ready) - return ret; - - if(!zfd_ismanaged(fd)) + if(!_zzuf_ready || !zfd_ismanaged(fd)) return ret; debug("close(%i) = %i", fd, ret); diff --git a/src/load-stream.c b/src/load-stream.c index ccc5257..c704013 100644 --- a/src/load-stream.c +++ b/src/load-stream.c @@ -121,20 +121,27 @@ int fseek(FILE *stream, long offset, int whence) ret = fseek_orig(stream, offset, whence); debug("fseek(%p, %li, %i) = %i", stream, offset, whence, ret); - if(ret == 0) + if(ret != 0) + return ret; + + switch(whence) { - switch(whence) - { - case SEEK_SET: zfd_setpos(fd, offset); break; - case SEEK_CUR: zfd_addpos(fd, offset); break; - case SEEK_END: zfd_setpos(fd, ftell(stream)); break; - } + case SEEK_END: + offset = ftell(stream); + /* fall through */ + case SEEK_SET: + zfd_setpos(fd, offset); + break; + case SEEK_CUR: + zfd_addpos(fd, offset); + break; } - return ret; + return 0; } size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream) { + long int pos; size_t ret; int fd; @@ -144,13 +151,17 @@ size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream) if(!_zzuf_ready || !zfd_ismanaged(fd)) return fread_orig(ptr, size, nmemb, stream); + pos = ftell(stream); ret = fread_orig(ptr, size, nmemb, stream); debug("fread(%p, %li, %li, %p) = %li", ptr, (long int)size, (long int)nmemb, stream, (long int)ret); - if(ret > 0) + if(ret >= 0) { - zzuf_fuzz(fd, ptr, ret * size); - zfd_addpos(fd, ret * size); + /* XXX: the number of bytes read is not ret * size, because + * a partial read may have advanced the stream pointer */ + long int newpos = ftell(stream); + zzuf_fuzz(fd, ptr, newpos - pos); + zfd_setpos(fd, newpos); } return ret; }