am 7cb19579: Merge "Add close_file flag to OpenArchiveFd()"

* commit '7cb19579bc22bf38e15b970f801f8065d629611d':
  Add close_file flag to OpenArchiveFd()
diff --git a/include/ziparchive/zip_archive.h b/include/ziparchive/zip_archive.h
index 7da6e84..386a390 100644
--- a/include/ziparchive/zip_archive.h
+++ b/include/ziparchive/zip_archive.h
@@ -101,6 +101,9 @@
  * Sets handle to the value of the opaque handle for this file descriptor.
  * This handle must be released by calling CloseArchive with this handle.
  *
+ * If assume_ownership parameter is 'true' calling CloseArchive will close
+ * the file.
+ *
  * This function maps and scans the central directory and builds a table
  * of entries for future lookups.
  *
@@ -109,7 +112,7 @@
  * Returns 0 on success, and negative values on failure.
  */
 int32_t OpenArchiveFd(const int fd, const char* debugFileName,
-                      ZipArchiveHandle *handle);
+                      ZipArchiveHandle *handle, bool assume_ownership = true);
 
 /*
  * Close archive, releasing resources associated with it. This will
diff --git a/libziparchive/zip_archive.cc b/libziparchive/zip_archive.cc
index b6fd0d2..afc122d 100644
--- a/libziparchive/zip_archive.cc
+++ b/libziparchive/zip_archive.cc
@@ -289,6 +289,7 @@
 struct ZipArchive {
   /* open Zip archive */
   const int fd;
+  const bool close_file;
 
   /* mapped central directory area */
   off64_t directory_offset;
@@ -306,8 +307,9 @@
   uint32_t hash_table_size;
   ZipEntryName* hash_table;
 
-  ZipArchive(const int fd) :
+  ZipArchive(const int fd, bool assume_ownership) :
       fd(fd),
+      close_file(assume_ownership),
       directory_offset(0),
       directory_map(NULL),
       num_entries(0),
@@ -315,7 +317,7 @@
       hash_table(NULL) {}
 
   ~ZipArchive() {
-    if (fd >= 0) {
+    if (close_file && fd >= 0) {
       close(fd);
     }
 
@@ -690,21 +692,22 @@
 }
 
 int32_t OpenArchiveFd(int fd, const char* debug_file_name,
-                      ZipArchiveHandle* handle) {
-  ZipArchive* archive = new ZipArchive(fd);
+                      ZipArchiveHandle* handle, bool assume_ownership) {
+  ZipArchive* archive = new ZipArchive(fd, assume_ownership);
   *handle = archive;
   return OpenArchiveInternal(archive, debug_file_name);
 }
 
 int32_t OpenArchive(const char* fileName, ZipArchiveHandle* handle) {
   const int fd = open(fileName, O_RDONLY | O_BINARY, 0);
-  ZipArchive* archive = new ZipArchive(fd);
+  ZipArchive* archive = new ZipArchive(fd, true);
   *handle = archive;
 
   if (fd < 0) {
     ALOGW("Unable to open '%s': %s", fileName, strerror(errno));
     return kIoError;
   }
+
   return OpenArchiveInternal(archive, fileName);
 }
 
diff --git a/libziparchive/zip_archive_test.cc b/libziparchive/zip_archive_test.cc
index 4775de0..c8dafa9 100644
--- a/libziparchive/zip_archive_test.cc
+++ b/libziparchive/zip_archive_test.cc
@@ -17,6 +17,7 @@
 #include "ziparchive/zip_archive.h"
 
 #include <errno.h>
+#include <fcntl.h>
 #include <getopt.h>
 #include <stdio.h>
 #include <unistd.h>
@@ -88,6 +89,26 @@
   ASSERT_EQ(-1, GetFileDescriptor(handle));
 }
 
+TEST(ziparchive, OpenAssumeFdOwnership) {
+  int fd = open((test_data_dir + "/" + kValidZip).c_str(), O_RDONLY);
+  ASSERT_NE(-1, fd);
+  ZipArchiveHandle handle;
+  ASSERT_EQ(0, OpenArchiveFd(fd, "OpenWithAssumeFdOwnership", &handle));
+  CloseArchive(handle);
+  ASSERT_EQ(-1, lseek(fd, 0, SEEK_SET));
+  ASSERT_EQ(EBADF, errno);
+}
+
+TEST(ziparchive, OpenDoNotAssumeFdOwnership) {
+  int fd = open((test_data_dir + "/" + kValidZip).c_str(), O_RDONLY);
+  ASSERT_NE(-1, fd);
+  ZipArchiveHandle handle;
+  ASSERT_EQ(0, OpenArchiveFd(fd, "OpenWithAssumeFdOwnership", &handle, false));
+  CloseArchive(handle);
+  ASSERT_EQ(0, lseek(fd, 0, SEEK_SET));
+  close(fd);
+}
+
 TEST(ziparchive, Iteration) {
   ZipArchiveHandle handle;
   ASSERT_EQ(0, OpenArchiveWrapper(kValidZip, &handle));