summaryrefslogtreecommitdiffstats
path: root/lib/libarchive/archive_write_set_compression_none.c
diff options
context:
space:
mode:
authorkientzle <kientzle@FreeBSD.org>2006-11-26 19:00:50 +0000
committerkientzle <kientzle@FreeBSD.org>2006-11-26 19:00:50 +0000
commit0f8fa3629e664a8cdfd6022cc1840102e3ff8c2c (patch)
treeebb3f03dd6640df049cc9396f4d753c10aa6ccc4 /lib/libarchive/archive_write_set_compression_none.c
parent24b0d3f0fdb86f7a4f9ecc9d9a8d01046094ed63 (diff)
downloadFreeBSD-src-0f8fa3629e664a8cdfd6022cc1840102e3ff8c2c.zip
FreeBSD-src-0f8fa3629e664a8cdfd6022cc1840102e3ff8c2c.tar.gz
Write-blocking cleanup, largely thanks to Colin Percival (cperciva@).
* If write block size is zero, don't block at all. This supports the unusual requirement of applications that need "no-delay" writes. * Expose _write_finish_entry() to give such applications more control over write boundaries. (Normal applications do not need this, as entries are completed automatically.) * Correct the type of write callbacks; this is a minor API change that does not affect the ABI. * Correct the error handling in _write_next_header() around completing the previous entry. * Correct the documentation for block-size markers: Remove docs for the long-defunct _read_set_block_size(); document all of the write block size manipulators. MFC after: 14 days
Diffstat (limited to 'lib/libarchive/archive_write_set_compression_none.c')
-rw-r--r--lib/libarchive/archive_write_set_compression_none.c37
1 files changed, 29 insertions, 8 deletions
diff --git a/lib/libarchive/archive_write_set_compression_none.c b/lib/libarchive/archive_write_set_compression_none.c
index 9e43365..3fdaa67 100644
--- a/lib/libarchive/archive_write_set_compression_none.c
+++ b/lib/libarchive/archive_write_set_compression_none.c
@@ -89,13 +89,14 @@ archive_compressor_none_init(struct archive *a)
memset(state, 0, sizeof(*state));
state->buffer_size = a->bytes_per_block;
- state->buffer = (char *)malloc(state->buffer_size);
-
- if (state->buffer == NULL) {
- archive_set_error(a, ENOMEM,
- "Can't allocate output buffer");
- free(state);
- return (ARCHIVE_FATAL);
+ if (state->buffer_size != 0) {
+ state->buffer = (char *)malloc(state->buffer_size);
+ if (state->buffer == NULL) {
+ archive_set_error(a, ENOMEM,
+ "Can't allocate output buffer");
+ free(state);
+ return (ARCHIVE_FATAL);
+ }
}
state->next = state->buffer;
@@ -129,7 +130,27 @@ archive_compressor_none_write(struct archive *a, const void *vbuff,
}
remaining = length;
- while (remaining > 0) {
+
+ /*
+ * If there is no buffer for blocking, just pass the data
+ * straight through to the client write callback. In
+ * particular, this supports "no write delay" operation for
+ * special applications. Just set the block size to zero.
+ */
+ if (state->buffer_size == 0) {
+ while (remaining > 0) {
+ bytes_written = (a->client_writer)(a, a->client_data,
+ buff, remaining);
+ if (bytes_written <= 0)
+ return (ARCHIVE_FATAL);
+ remaining -= bytes_written;
+ buff += bytes_written;
+ }
+ a->file_position += length;
+ return (ARCHIVE_OK);
+ }
+
+ while ((remaining > 0) || (state->avail == 0)) {
/*
* If we have a full output block, write it and reset the
* output buffer.
OpenPOWER on IntegriCloud