diff options
author | pixdamix <pixdamix@e8e0d7a0-c8d9-11dd-a880-a1081c7ac358> | 2009-10-27 17:15:50 (EDT) |
---|---|---|
committer | pixdamix <pixdamix@e8e0d7a0-c8d9-11dd-a880-a1081c7ac358> | 2009-10-27 17:15:50 (EDT) |
commit | 3c9460a62e86e92cac8695317efb6d56ecabfb71 (patch) | |
tree | 03bd31950f71291690aa2c38a104230c34e7116c | |
parent | 587f690ff0ba0ec6b91bd4b83fa39305120e8e93 (diff) |
Improve the poor man's fseek in unarchive.c
Modified seek_sub_file since the fgetc in the for loop
was very slow when installing huge packages.
A test on my machine showed a 4x gain when installing
a large package (23Mib)
git-svn-id: http://opkg.googlecode.com/svn/trunk@222 e8e0d7a0-c8d9-11dd-a880-a1081c7ac358
-rw-r--r-- | libbb/unarchive.c | 28 |
1 files changed, 22 insertions, 6 deletions
diff --git a/libbb/unarchive.c b/libbb/unarchive.c index d0896ba..a2ae0cb 100644 --- a/libbb/unarchive.c +++ b/libbb/unarchive.c @@ -38,6 +38,7 @@ static char *linkname = NULL; extern void seek_sub_file(FILE *src_stream, const int count); extern char *extract_archive(FILE *src_stream, FILE *out_stream, const file_header_t *file_entry, const int function, const char *prefix); +extern ssize_t seek_by_read(FILE* fd, size_t len); #ifdef L_archive_offset @@ -47,16 +48,31 @@ extern off_t archive_offset; #endif #ifdef L_seek_sub_file +#define SEEK_BUF 4096 +ssize_t seek_by_read(FILE* fd, size_t len) +{ + ssize_t cc, total = 0; + char buf[SEEK_BUF]; + + while (len) { + cc = fread(buf, sizeof(buf[0]), + len > SEEK_BUF ? SEEK_BUF : len, + fd); + + total += cc; + len -= cc; + + if(feof(fd) || ferror(fd)) + break; + } + return total; +} + void seek_sub_file(FILE *src_stream, const int count) { - int i; /* Try to fseek as faster */ archive_offset += count; - // if (fseek(src_stream, count, SEEK_CUR) != 0 && errno == ESPIPE) { - for (i = 0; i < count; i++) { - fgetc(src_stream); - } - //} + seek_by_read(src_stream, count); return; } #endif |