Fix double close in dex2oat when BCP is passed as FDs

Bug: 191052821
Test: Modify odrefresh to pass BCP as FDs to dex2oat. Run w/ --force-compile.
      # With thix fix, no longer seeing "fdsan: double-close of file
      descriptor 24 detected"

Change-Id: Iac09b06c8e7aa93114896632cdea6c610662455b
diff --git a/libartbase/base/zip_archive.cc b/libartbase/base/zip_archive.cc
index 6abcdc5..70778e7 100644
--- a/libartbase/base/zip_archive.cc
+++ b/libartbase/base/zip_archive.cc
@@ -246,11 +246,22 @@
 }
 
 ZipArchive* ZipArchive::OpenFromFd(int fd, const char* filename, std::string* error_msg) {
+  return OpenFromFdInternal(fd, /*assume_ownership=*/true, filename, error_msg);
+}
+
+ZipArchive* ZipArchive::OpenFromOwnedFd(int fd, const char* filename, std::string* error_msg) {
+  return OpenFromFdInternal(fd, /*assume_ownership=*/false, filename, error_msg);
+}
+
+ZipArchive* ZipArchive::OpenFromFdInternal(int fd,
+                                           bool assume_ownership,
+                                           const char* filename,
+                                           std::string* error_msg) {
   DCHECK(filename != nullptr);
   DCHECK_GT(fd, 0);
 
   ZipArchiveHandle handle;
-  const int32_t error = OpenArchiveFd(fd, filename, &handle);
+  const int32_t error = OpenArchiveFd(fd, filename, &handle, assume_ownership);
   if (error != 0) {
     *error_msg = std::string(ErrorCodeString(error));
     CloseArchive(handle);
diff --git a/libartbase/base/zip_archive.h b/libartbase/base/zip_archive.h
index a4e56b5..29c5ea1 100644
--- a/libartbase/base/zip_archive.h
+++ b/libartbase/base/zip_archive.h
@@ -92,12 +92,18 @@
   // return new ZipArchive instance on success, null on error.
   static ZipArchive* Open(const char* filename, std::string* error_msg);
   static ZipArchive* OpenFromFd(int fd, const char* filename, std::string* error_msg);
+  static ZipArchive* OpenFromOwnedFd(int fd, const char* filename, std::string* error_msg);
 
   ZipEntry* Find(const char* name, std::string* error_msg) const;
 
   ~ZipArchive();
 
  private:
+  static ZipArchive* OpenFromFdInternal(int fd,
+                                        bool assume_ownership,
+                                        const char* filename,
+                                        std::string* error_msg);
+
   explicit ZipArchive(ZipArchiveHandle handle) : handle_(handle) {}
 
   friend class ZipEntry;
diff --git a/runtime/interpreter/unstarted_runtime.cc b/runtime/interpreter/unstarted_runtime.cc
index 9ed3b5e..5fd9af5 100644
--- a/runtime/interpreter/unstarted_runtime.cc
+++ b/runtime/interpreter/unstarted_runtime.cc
@@ -484,7 +484,7 @@
   result->SetZ(class_name == nullptr);
 }
 
-static MemMap FindAndExtractEntry(const std::string& jar_file,
+static MemMap FindAndExtractEntry(const std::string& bcp_jar_file,
                                   int jar_fd,
                                   const char* entry_name,
                                   size_t* size,
@@ -493,9 +493,9 @@
 
   std::unique_ptr<ZipArchive> zip_archive;
   if (jar_fd >= 0) {
-    zip_archive.reset(ZipArchive::OpenFromFd(jar_fd, jar_file.c_str(), error_msg));
+    zip_archive.reset(ZipArchive::OpenFromOwnedFd(jar_fd, bcp_jar_file.c_str(), error_msg));
   } else {
-    zip_archive.reset(ZipArchive::Open(jar_file.c_str(), error_msg));
+    zip_archive.reset(ZipArchive::Open(bcp_jar_file.c_str(), error_msg));
   }
   if (zip_archive == nullptr) {
     return MemMap::Invalid();
@@ -504,7 +504,7 @@
   if (zip_entry == nullptr) {
     return MemMap::Invalid();
   }
-  MemMap tmp_map = zip_entry->ExtractToMemMap(jar_file.c_str(), entry_name, error_msg);
+  MemMap tmp_map = zip_entry->ExtractToMemMap(bcp_jar_file.c_str(), entry_name, error_msg);
   if (!tmp_map.IsValid()) {
     return MemMap::Invalid();
   }