]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
Flush write filters between entries.
authorDag-Erling Smørgrav <des@des.no>
Mon, 14 Nov 2022 18:05:42 +0000 (19:05 +0100)
committerMartin Matuška <martin@matuska.de>
Mon, 9 Jan 2023 14:23:53 +0000 (15:23 +0100)
* 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.

libarchive/archive_write.c
libarchive/archive_write_private.h

index 27626b54147fd83390fdb7fc8fa292219d62b320..ec3c95c56685eefea63cb58e4017e038058ea219 100644 (file)
@@ -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) {
index 155fdd734887e4005221c0c9dd45932830913234..6522e6521beb5b3779ca93bfbf66199e8068073a 100644 (file)
@@ -53,6 +53,7 @@ struct archive_write_filter {
            const char *key, const char *value);
        int     (*open)(struct archive_write_filter *);
        int     (*write)(struct archive_write_filter *, const void *, size_t);
+       int     (*flush)(struct archive_write_filter *);
        int     (*close)(struct archive_write_filter *);
        int     (*free)(struct archive_write_filter *);
        void     *data;