summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorcperciva <cperciva@FreeBSD.org>2007-01-04 12:45:00 +0000
committercperciva <cperciva@FreeBSD.org>2007-01-04 12:45:00 +0000
commit3756545e6cb2c9386c5ba5538ad35065e0ffe8a0 (patch)
tree35a0125ff7a7fb9d2bf0e904d923613dc0ac3a98 /lib
parentae96850d62b1d020b090d570ced8362ba847a7d1 (diff)
downloadFreeBSD-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.h2
-rw-r--r--lib/libarchive/archive_read_support_compression_none.c19
-rw-r--r--lib/libarchive/archive_read_support_format_iso9660.c4
-rw-r--r--lib/libarchive/archive_read_support_format_tar.c2
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;
OpenPOWER on IntegriCloud