Fix java.util.zip.ZipFile with OPEN_DELETE.

openJdk java.util.zip.ZipFile with OPEN_DELETE flag
uses unlink to remove the file just after it's opened.

This is causing trouble on /storage partition, we
can read/write unlinked file easily, but lseek seems
to fail with ENOENT.

This change introduces alternative implementation that
doesn't use unlink before closing the file.

Bug: 28901232
Bug: 28950284
Change-Id: I871a84e9a14bc1b4b9d5b0faa207579e27bcfc81
diff --git a/ojluni/src/main/java/java/util/zip/ZipFile.java b/ojluni/src/main/java/java/util/zip/ZipFile.java
index 0535a0e..e6624af 100755
--- a/ojluni/src/main/java/java/util/zip/ZipFile.java
+++ b/ojluni/src/main/java/java/util/zip/ZipFile.java
@@ -68,6 +68,10 @@
 
     private final CloseGuard guard = CloseGuard.get();
 
+    // Android changed, needed for alternative OPEN_DELETE implementation
+    // that doesn't use unlink before closing the file.
+    private final File fileToRemoveOnClose;
+
     private static final int STORED = ZipEntry.STORED;
     private static final int DEFLATED = ZipEntry.DEFLATED;
 
@@ -204,13 +208,10 @@
             throw new ZipException("File too short to be a zip file: " + file.length());
         }
         String name = file.getPath();
-        SecurityManager sm = System.getSecurityManager();
-        if (sm != null) {
-            sm.checkRead(name);
-            if ((mode & OPEN_DELETE) != 0) {
-                sm.checkDelete(name);
-            }
-        }
+
+        // Android changed, handle OPEN_DELETE case in #close().
+        fileToRemoveOnClose = ((mode & OPEN_DELETE) != 0) ? file : null;
+
         if (charset == null)
             throw new NullPointerException("charset is null");
         this.zc = ZipCoder.get(charset);
@@ -616,6 +617,11 @@
 
                 close(zf);
             }
+
+            // Android-changed, explicit delete for OPEN_DELETE ZipFile.
+            if (fileToRemoveOnClose != null) {
+                fileToRemoveOnClose.delete();
+            }
         }
     }
 
diff --git a/ojluni/src/main/native/java_util_zip_ZipFile.c b/ojluni/src/main/native/java_util_zip_ZipFile.c
index a57e20e..7280d97 100644
--- a/ojluni/src/main/native/java_util_zip_ZipFile.c
+++ b/ojluni/src/main/native/java_util_zip_ZipFile.c
@@ -95,7 +95,8 @@
     jzfile *zip = 0;
 
     if (mode & OPEN_READ) flag |= O_RDONLY;
-    if (mode & OPEN_DELETE) flag |= JVM_O_DELETE;
+    // Android changed, JVM_O_DELETE/unlink is problematic, see b/28901232.
+    //if (mode & OPEN_DELETE) flag |= JVM_O_DELETE;
 
     if (path != 0) {
         zip = ZIP_Get_From_Cache(path, &msg, lastModified);
diff --git a/ojluni/src/main/native/jvm_md.h b/ojluni/src/main/native/jvm_md.h
index 390e89c..a366445 100755
--- a/ojluni/src/main/native/jvm_md.h
+++ b/ojluni/src/main/native/jvm_md.h
@@ -75,6 +75,8 @@
 #define JVM_O_O_APPEND   O_APPEND
 #define JVM_O_EXCL       O_EXCL
 #define JVM_O_CREAT      O_CREAT
+// JVM_O_DELETE use is discouraged (until b/28950284 is fixed),
+// may cause bugs on some filesystems.
 #define JVM_O_DELETE     0x10000
 
 /* Signals */