summaryrefslogtreecommitdiffstats
path: root/Utilities/cmlibarchive/libarchive/archive_write.c
diff options
context:
space:
mode:
Diffstat (limited to 'Utilities/cmlibarchive/libarchive/archive_write.c')
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write.c59
1 files changed, 33 insertions, 26 deletions
diff --git a/Utilities/cmlibarchive/libarchive/archive_write.c b/Utilities/cmlibarchive/libarchive/archive_write.c
index 8d70f51..66592e8 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write.c
@@ -60,8 +60,6 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_write.c 201099 2009-12-28 03:03:
#include "archive_private.h"
#include "archive_write_private.h"
-static struct archive_vtable *archive_write_vtable(void);
-
static int _archive_filter_code(struct archive *, int);
static const char *_archive_filter_name(struct archive *, int);
static int64_t _archive_filter_bytes(struct archive *, int);
@@ -79,26 +77,18 @@ struct archive_none {
char *next;
};
-static struct archive_vtable *
-archive_write_vtable(void)
-{
- static struct archive_vtable av;
- static int inited = 0;
-
- if (!inited) {
- av.archive_close = _archive_write_close;
- av.archive_filter_bytes = _archive_filter_bytes;
- av.archive_filter_code = _archive_filter_code;
- av.archive_filter_name = _archive_filter_name;
- av.archive_filter_count = _archive_write_filter_count;
- av.archive_free = _archive_write_free;
- av.archive_write_header = _archive_write_header;
- av.archive_write_finish_entry = _archive_write_finish_entry;
- av.archive_write_data = _archive_write_data;
- inited = 1;
- }
- return (&av);
-}
+static const struct archive_vtable
+archive_write_vtable = {
+ .archive_close = _archive_write_close,
+ .archive_filter_bytes = _archive_filter_bytes,
+ .archive_filter_code = _archive_filter_code,
+ .archive_filter_name = _archive_filter_name,
+ .archive_filter_count = _archive_write_filter_count,
+ .archive_free = _archive_write_free,
+ .archive_write_header = _archive_write_header,
+ .archive_write_finish_entry = _archive_write_finish_entry,
+ .archive_write_data = _archive_write_data,
+};
/*
* Allocate, initialize and return an archive object.
@@ -114,7 +104,7 @@ archive_write_new(void)
return (NULL);
a->archive.magic = ARCHIVE_WRITE_MAGIC;
a->archive.state = ARCHIVE_STATE_NEW;
- a->archive.vtable = archive_write_vtable();
+ a->archive.vtable = &archive_write_vtable;
/*
* The value 10240 here matches the traditional tar default,
* but is otherwise arbitrary.
@@ -482,6 +472,8 @@ archive_write_client_close(struct archive_write_filter *f)
ssize_t block_length;
ssize_t target_block_length;
ssize_t bytes_written;
+ size_t to_write;
+ char *p;
int ret = ARCHIVE_OK;
/* If there's pending data, pad and write the last block */
@@ -504,9 +496,24 @@ archive_write_client_close(struct archive_write_filter *f)
target_block_length - block_length);
block_length = target_block_length;
}
- bytes_written = (a->client_writer)(&a->archive,
- a->client_data, state->buffer, block_length);
- ret = bytes_written <= 0 ? ARCHIVE_FATAL : ARCHIVE_OK;
+ p = state->buffer;
+ to_write = block_length;
+ while (to_write > 0) {
+ bytes_written = (a->client_writer)(&a->archive,
+ a->client_data, p, to_write);
+ if (bytes_written <= 0) {
+ ret = ARCHIVE_FATAL;
+ break;
+ }
+ if ((size_t)bytes_written > to_write) {
+ archive_set_error(&(a->archive),
+ -1, "write overrun");
+ ret = ARCHIVE_FATAL;
+ break;
+ }
+ p += bytes_written;
+ to_write -= bytes_written;
+ }
}
if (a->client_closer)
(*a->client_closer)(&a->archive, a->client_data);