diff options
author | Dag-Erling Smørgrav <des@des.no> | 2022-11-14 19:05:42 +0100 |
---|---|---|
committer | Martin Matuška <martin@matuska.de> | 2023-01-09 15:23:53 +0100 |
commit | 9de87afec611783439b260bc20f1fc088ad4bbc8 (patch) | |
tree | 2b2ab50a33fb8824d65211f1e31aaad05347ec01 /libarchive/archive_write.c | |
parent | c7b51f04c57bac386be9548b68bee7d511f18a76 (diff) | |
download | libarchive-9de87afec611783439b260bc20f1fc088ad4bbc8.tar.gz |
Flush write filters between entries.
* Add a flush() method to write filters.
* Add an __archive_write_filters_flush() function which iterates over filters in order and invokes the flush method for any filter that has one and that has written data.
* Call __archive_write_filters_flush() before writing a new header.
Diffstat (limited to 'libarchive/archive_write.c')
-rw-r--r-- | libarchive/archive_write.c | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/libarchive/archive_write.c b/libarchive/archive_write.c index 27626b54..ec3c95c5 100644 --- a/libarchive/archive_write.c +++ b/libarchive/archive_write.c @@ -310,6 +310,25 @@ __archive_write_output(struct archive_write *a, const void *buff, size_t length) return (__archive_write_filter(a->filter_first, buff, length)); } +static int +__archive_write_filters_flush(struct archive_write *a) +{ + struct archive_write_filter *f; + int ret, ret1; + + ret = ARCHIVE_OK; + for (f = a->filter_first; f != NULL; f = f->next_filter) { + if (f->flush != NULL && f->bytes_written > 0) { + ret1 = (f->flush)(f); + if (ret1 < ret) + ret = ret1; + if (ret1 < ARCHIVE_WARN) + f->state = ARCHIVE_WRITE_FILTER_STATE_FATAL; + } + } + return (ret); +} + int __archive_write_nulls(struct archive_write *a, size_t length) { @@ -740,6 +759,18 @@ _archive_write_header(struct archive *_a, struct archive_entry *entry) return (ARCHIVE_FAILED); } + /* Flush filters at boundary. */ + r2 = __archive_write_filters_flush(a); + if (r2 == ARCHIVE_FAILED) { + return (ARCHIVE_FAILED); + } + if (r2 == ARCHIVE_FATAL) { + a->archive.state = ARCHIVE_STATE_FATAL; + return (ARCHIVE_FATAL); + } + if (r2 < ret) + ret = r2; + /* Format and write header. */ r2 = ((a->format_write_header)(a, entry)); if (r2 == ARCHIVE_FAILED) { |