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.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.c')
-rw-r--r-- | lib/libarchive/archive_write.c | 33 |
1 files changed, 25 insertions, 8 deletions
diff --git a/lib/libarchive/archive_write.c b/lib/libarchive/archive_write.c index aa50c70..4b288bf 100644 --- a/lib/libarchive/archive_write.c +++ b/lib/libarchive/archive_write.c @@ -232,22 +232,22 @@ archive_write_finish(struct archive *a) free(a); } - /* * Write the appropriate header. */ int archive_write_header(struct archive *a, struct archive_entry *entry) { - int ret; + int ret, r2; __archive_check_magic(a, ARCHIVE_WRITE_MAGIC, - ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA, "archive_write_header"); + ARCHIVE_STATE_DATA | ARCHIVE_STATE_HEADER, "archive_write_header"); archive_string_empty(&a->error_string); - /* Finish last entry. */ - if (a->state & ARCHIVE_STATE_DATA) - ((a->format_finish_entry)(a)); + /* In particular, "retry" and "fatal" get returned immediately. */ + ret = archive_write_finish_entry(a); + if (ret < ARCHIVE_OK && ret != ARCHIVE_WARN) + return (ret); if (a->skip_file_dev != 0 && archive_entry_dev(entry) == a->skip_file_dev && @@ -258,12 +258,28 @@ archive_write_header(struct archive *a, struct archive_entry *entry) } /* Format and write header. */ - ret = ((a->format_write_header)(a, entry)); + r2 = ((a->format_write_header)(a, entry)); + if (r2 < ret) + ret = r2; a->state = ARCHIVE_STATE_DATA; return (ret); } +int +archive_write_finish_entry(struct archive * a) +{ + int ret = ARCHIVE_OK; + + __archive_check_magic(a, ARCHIVE_WRITE_MAGIC, + ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA, + "archive_write_finish_entry"); + if (a->state & ARCHIVE_STATE_DATA) + ret = (a->format_finish_entry)(a); + a->state = ARCHIVE_STATE_HEADER; + return (ret); +} + /* * Note that the compressor is responsible for blocking. */ @@ -271,7 +287,8 @@ archive_write_header(struct archive *a, struct archive_entry *entry) int archive_write_data(struct archive *a, const void *buff, size_t s) { - __archive_check_magic(a, ARCHIVE_WRITE_MAGIC, ARCHIVE_STATE_DATA, "archive_write_data"); + __archive_check_magic(a, ARCHIVE_WRITE_MAGIC, + ARCHIVE_STATE_DATA, "archive_write_data"); archive_string_empty(&a->error_string); return ((a->format_write_data)(a, buff, s)); } |