From 3411f6cffdcf3c72e7cee3a263c40414dfef956e Mon Sep 17 00:00:00 2001
From: Max Kellermann <max@duempel.org>
Date: Tue, 15 Dec 2009 19:45:50 +0100
Subject: [PATCH] archive: close archive when stream is closed

Fixes a memory leak: the "archive" input plugin opens the archive, but
never closes it.  This patch moves the responsibility for doing that
to archive_plugin.open_stream().  This is an slight internal API
change, but it is the simplest and least intrusive fix for the memory
leak.
---
 NEWS                     | 2 ++
 src/archive/bz2_plugin.c | 2 ++
 src/archive/iso_plugin.c | 2 ++
 src/archive/zip_plugin.c | 2 ++
 src/archive_api.h        | 3 +++
 5 files changed, 11 insertions(+)

diff --git a/NEWS b/NEWS
index 6bcf328f8..7ead1f16e 100644
--- a/NEWS
+++ b/NEWS
@@ -1,4 +1,6 @@
 ver 0.15.7 (2009/??/??)
+* archive:
+  - close archive when stream is closed
 * input:
   - file: don't fall back to parent directory
   - archive: fixed memory leak in error handler
diff --git a/src/archive/bz2_plugin.c b/src/archive/bz2_plugin.c
index 78f13400a..0ef042e90 100644
--- a/src/archive/bz2_plugin.c
+++ b/src/archive/bz2_plugin.c
@@ -173,6 +173,8 @@ bz2_is_close(struct input_stream *is)
 	bz2_context *context = (bz2_context *) is->data;
 	bz2_destroy(context);
 	is->data = NULL;
+
+	bz2_close((struct archive_file *)context);
 }
 
 static int
diff --git a/src/archive/iso_plugin.c b/src/archive/iso_plugin.c
index d295f148f..7d2c075b1 100644
--- a/src/archive/iso_plugin.c
+++ b/src/archive/iso_plugin.c
@@ -165,6 +165,8 @@ iso_is_close(struct input_stream *is)
 {
 	iso_context *context = (iso_context *) is->data;
 	g_free(context->statbuf);
+
+	iso_close((struct archive_file *)context);
 }
 
 
diff --git a/src/archive/zip_plugin.c b/src/archive/zip_plugin.c
index dbd2534fa..2f08b3812 100644
--- a/src/archive/zip_plugin.c
+++ b/src/archive/zip_plugin.c
@@ -133,6 +133,8 @@ zip_is_close(struct input_stream *is)
 {
 	zip_context *context = (zip_context *) is->data;
 	zzip_file_close (context->file);
+
+	zip_close((struct archive_file *)context);
 }
 
 static size_t
diff --git a/src/archive_api.h b/src/archive_api.h
index dbd050bfa..2efcc1e6a 100644
--- a/src/archive_api.h
+++ b/src/archive_api.h
@@ -73,6 +73,9 @@ struct archive_plugin {
 	/**
 	 * Opens an input_stream of a file within the archive.
 	 *
+	 * If this function succeeds, then the #input_stream "owns"
+	 * the archive file and will automatically close it.
+	 *
 	 * @param path the path within the archive
 	 */
 	bool (*open_stream)(struct archive_file *, struct input_stream *is,