diff options
author | kientzle <kientzle@FreeBSD.org> | 2006-11-26 19:00:50 +0000 |
---|---|---|
committer | kientzle <kientzle@FreeBSD.org> | 2006-11-26 19:00:50 +0000 |
commit | 0f8fa3629e664a8cdfd6022cc1840102e3ff8c2c (patch) | |
tree | ebb3f03dd6640df049cc9396f4d753c10aa6ccc4 /lib/libarchive/archive_write_set_compression_none.c | |
parent | 24b0d3f0fdb86f7a4f9ecc9d9a8d01046094ed63 (diff) | |
download | FreeBSD-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.c | 37 |
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. |