diff options
author | cperciva <cperciva@FreeBSD.org> | 2007-01-04 12:45:00 +0000 |
---|---|---|
committer | cperciva <cperciva@FreeBSD.org> | 2007-01-04 12:45:00 +0000 |
commit | 3756545e6cb2c9386c5ba5538ad35065e0ffe8a0 (patch) | |
tree | 35a0125ff7a7fb9d2bf0e904d923613dc0ac3a98 /lib | |
parent | ae96850d62b1d020b090d570ced8362ba847a7d1 (diff) | |
download | FreeBSD-src-3756545e6cb2c9386c5ba5538ad35065e0ffe8a0.zip FreeBSD-src-3756545e6cb2c9386c5ba5538ad35065e0ffe8a0.tar.gz |
Convert compression_skip from taking a size_t skip length request and
returning the length skipped in a ssize_t to using off_t for both. This
does not break any A[BP]Is, since compression_skip is entirely internal
to libarchive.
If a skip request is > SSIZE_MAX, don't pass it down to the client layer
skip function, since those still uses size_t / ssize_t. Instead, just
read the data and throw it away.
With this commit, libarchive/bsdtar should now successfully skip archive
entries of >2GB on 32-bit systems, but does so slower than necessary.
The performance will improve with a future A[BP]I breaking commit which
makes client layer skip functions use off_t.
Discussed with: kientzle
MFC after: 1 week
Diffstat (limited to 'lib')
-rw-r--r-- | lib/libarchive/archive_private.h | 2 | ||||
-rw-r--r-- | lib/libarchive/archive_read_support_compression_none.c | 19 | ||||
-rw-r--r-- | lib/libarchive/archive_read_support_format_iso9660.c | 4 | ||||
-rw-r--r-- | lib/libarchive/archive_read_support_format_tar.c | 2 |
4 files changed, 15 insertions, 12 deletions
diff --git a/lib/libarchive/archive_private.h b/lib/libarchive/archive_private.h index 300b79d..0fa4138 100644 --- a/lib/libarchive/archive_private.h +++ b/lib/libarchive/archive_private.h @@ -133,7 +133,7 @@ struct archive { ssize_t (*compression_read_ahead)(struct archive *, const void **, size_t request); ssize_t (*compression_read_consume)(struct archive *, size_t); - ssize_t (*compression_skip)(struct archive *, size_t); + off_t (*compression_skip)(struct archive *, off_t); /* * Format detection is mostly the same as compression diff --git a/lib/libarchive/archive_read_support_compression_none.c b/lib/libarchive/archive_read_support_compression_none.c index 5003423..25e575e 100644 --- a/lib/libarchive/archive_read_support_compression_none.c +++ b/lib/libarchive/archive_read_support_compression_none.c @@ -31,6 +31,9 @@ __FBSDID("$FreeBSD$"); #ifdef HAVE_ERRNO_H #include <errno.h> #endif +#ifdef HAVE_LIMITS_H +#include <limits.h> +#endif #ifdef HAVE_STDLIB_H #include <stdlib.h> #endif @@ -80,7 +83,7 @@ static ssize_t archive_decompressor_none_read_ahead(struct archive *, const void **, size_t); static ssize_t archive_decompressor_none_read_consume(struct archive *, size_t); -static ssize_t archive_decompressor_none_skip(struct archive *, size_t); +static off_t archive_decompressor_none_skip(struct archive *, off_t); int archive_read_support_compression_none(struct archive *a) @@ -269,11 +272,11 @@ archive_decompressor_none_read_consume(struct archive *a, size_t request) * ARCHIVE_FATAL. Note that this differs from the contract for * read_ahead, which does not guarantee a minimum count. */ -static ssize_t -archive_decompressor_none_skip(struct archive *a, size_t request) +static off_t +archive_decompressor_none_skip(struct archive *a, off_t request) { struct archive_decompress_none *state; - ssize_t bytes_skipped, total_bytes_skipped = 0; + off_t bytes_skipped, total_bytes_skipped = 0; size_t min; state = (struct archive_decompress_none *)a->compression_data; @@ -283,13 +286,13 @@ archive_decompressor_none_skip(struct archive *a, size_t request) * If there is data in the buffers already, use that first. */ if (state->avail > 0) { - min = minimum(request, state->avail); + min = minimum(request, (off_t)state->avail); bytes_skipped = archive_decompressor_none_read_consume(a, min); request -= bytes_skipped; total_bytes_skipped += bytes_skipped; } if (state->client_avail > 0) { - min = minimum(request, state->client_avail); + min = minimum(request, (off_t)state->client_avail); bytes_skipped = archive_decompressor_none_read_consume(a, min); request -= bytes_skipped; total_bytes_skipped += bytes_skipped; @@ -299,7 +302,7 @@ archive_decompressor_none_skip(struct archive *a, size_t request) /* * If a client_skipper was provided, try that first. */ - if (a->client_skipper != NULL) { + if ((a->client_skipper != NULL) && (request < SSIZE_MAX)) { bytes_skipped = (a->client_skipper)(a, a->client_data, request); if (bytes_skipped < 0) { /* error */ @@ -335,7 +338,7 @@ archive_decompressor_none_skip(struct archive *a, size_t request) return (ARCHIVE_FATAL); } assert(bytes_read >= 0); /* precondition for cast below */ - min = minimum((size_t)bytes_read, request); + min = (size_t)(minimum(bytes_read, request)); bytes_read = archive_decompressor_none_read_consume(a, min); total_bytes_skipped += bytes_read; request -= bytes_read; diff --git a/lib/libarchive/archive_read_support_format_iso9660.c b/lib/libarchive/archive_read_support_format_iso9660.c index 7ef079f..c5db328 100644 --- a/lib/libarchive/archive_read_support_format_iso9660.c +++ b/lib/libarchive/archive_read_support_format_iso9660.c @@ -919,8 +919,8 @@ fprintf(stderr, " *** Discarding CE data.\n"); /* Use fast compression_skip if it's available. */ if (iso9660->current_position < offset && a->compression_skip != NULL) { - ssize_t step = offset - iso9660->current_position; - ssize_t bytes_read; + off_t step = offset - iso9660->current_position; + off_t bytes_read; bytes_read = (a->compression_skip)(a, step); iso9660->current_position += bytes_read; } diff --git a/lib/libarchive/archive_read_support_format_tar.c b/lib/libarchive/archive_read_support_format_tar.c index b645f7e..f10a14b 100644 --- a/lib/libarchive/archive_read_support_format_tar.c +++ b/lib/libarchive/archive_read_support_format_tar.c @@ -541,7 +541,7 @@ archive_read_format_tar_read_data(struct archive *a, static int archive_read_format_tar_skip(struct archive *a) { - ssize_t bytes_skipped; + off_t bytes_skipped; struct tar* tar; struct sparse_block *p; int r = ARCHIVE_OK; |