RRO: Synchronize access to overlays.list am: 0fbb608110
am: dce79f10ba

Change-Id: Idc121ffe64f1bc7b5bdcb1a800305165f27f1c0a
diff --git a/cmds/idmap/scan.cpp b/cmds/idmap/scan.cpp
index 6d30f0d..ab6adfb 100644
--- a/cmds/idmap/scan.cpp
+++ b/cmds/idmap/scan.cpp
@@ -1,5 +1,6 @@
 #include <dirent.h>
 #include <inttypes.h>
+#include <sys/file.h>
 #include <sys/stat.h>
 
 #include "idmap.h"
@@ -35,16 +36,31 @@
 
     bool writePackagesList(const char *filename, const SortedVector<Overlay>& overlayVector)
     {
-        FILE* fout = fopen(filename, "w");
+        // the file is opened for appending so that it doesn't get truncated
+        // before we can guarantee mutual exclusion via the flock
+        FILE* fout = fopen(filename, "a");
         if (fout == NULL) {
             return false;
         }
 
+        if (TEMP_FAILURE_RETRY(flock(fileno(fout), LOCK_EX)) != 0) {
+            fclose(fout);
+            return false;
+        }
+
+        if (TEMP_FAILURE_RETRY(ftruncate(fileno(fout), 0)) != 0) {
+            TEMP_FAILURE_RETRY(flock(fileno(fout), LOCK_UN));
+            fclose(fout);
+            return false;
+        }
+
         for (size_t i = 0; i < overlayVector.size(); ++i) {
             const Overlay& overlay = overlayVector[i];
             fprintf(fout, "%s %s\n", overlay.apk_path.string(), overlay.idmap_path.string());
         }
 
+        TEMP_FAILURE_RETRY(fflush(fout));
+        TEMP_FAILURE_RETRY(flock(fileno(fout), LOCK_UN));
         fclose(fout);
 
         // Make file world readable since Zygote (running as root) will read
@@ -171,9 +187,6 @@
 {
     String8 filename = String8(idmap_dir);
     filename.appendPath("overlays.list");
-    if (unlink(filename.string()) != 0 && errno != ENOENT) {
-        return EXIT_FAILURE;
-    }
 
     SortedVector<Overlay> overlayVector;
     const size_t N = overlay_dirs->size();
diff --git a/libs/androidfw/AssetManager.cpp b/libs/androidfw/AssetManager.cpp
index 0439898..4c1c1b9 100644
--- a/libs/androidfw/AssetManager.cpp
+++ b/libs/androidfw/AssetManager.cpp
@@ -35,6 +35,9 @@
 #include <utils/threads.h>
 #include <utils/Timers.h>
 #include <utils/Trace.h>
+#ifndef _WIN32
+#include <sys/file.h>
+#endif
 
 #include <assert.h>
 #include <dirent.h>
@@ -768,6 +771,12 @@
         return;
     }
 
+#ifndef _WIN32
+    if (TEMP_FAILURE_RETRY(flock(fileno(fin), LOCK_SH)) != 0) {
+        fclose(fin);
+        return;
+    }
+#endif
     char buf[1024];
     while (fgets(buf, sizeof(buf), fin)) {
         // format of each line:
@@ -798,6 +807,10 @@
             const_cast<AssetManager*>(this)->mZipSet.addOverlay(targetPackagePath, oap);
         }
     }
+
+#ifndef _WIN32
+    TEMP_FAILURE_RETRY(flock(fileno(fin), LOCK_UN));
+#endif
     fclose(fin);
 }