Merge "Expose libandroidicu to llndk namespace"
diff --git a/base/cmsg.cpp b/base/cmsg.cpp
index 5e86075..42866f8 100644
--- a/base/cmsg.cpp
+++ b/base/cmsg.cpp
@@ -16,8 +16,8 @@
 
 #include <android-base/cmsg.h>
 
-#include <alloca.h>
 #include <errno.h>
+#include <fcntl.h>
 #include <stdlib.h>
 #include <sys/socket.h>
 #include <sys/user.h>
@@ -46,7 +46,8 @@
       .msg_iov = &iov,
       .msg_iovlen = 1,
       .msg_control = cmsg_buf,
-      .msg_controllen = cmsg_space,
+      // We can't cast to the actual type of the field, because it's different across platforms.
+      .msg_controllen = static_cast<unsigned int>(cmsg_space),
       .msg_flags = 0,
   };
 
@@ -60,7 +61,13 @@
     cmsg_fds[i] = fds[i];
   }
 
-  return TEMP_FAILURE_RETRY(sendmsg(sockfd, &msg, MSG_NOSIGNAL));
+#if defined(__linux__)
+  int flags = MSG_NOSIGNAL;
+#else
+  int flags = 0;
+#endif
+
+  return TEMP_FAILURE_RETRY(sendmsg(sockfd, &msg, flags));
 }
 
 ssize_t ReceiveFileDescriptorVector(int sockfd, void* data, size_t len, size_t max_fds,
@@ -81,12 +88,18 @@
       .msg_iov = &iov,
       .msg_iovlen = 1,
       .msg_control = cmsg_buf,
-      .msg_controllen = cmsg_space,
+      // We can't cast to the actual type of the field, because it's different across platforms.
+      .msg_controllen = static_cast<unsigned int>(cmsg_space),
       .msg_flags = 0,
   };
 
-  ssize_t rc = TEMP_FAILURE_RETRY(
-      recvmsg(sockfd, &msg, MSG_TRUNC | MSG_CTRUNC | MSG_CMSG_CLOEXEC | MSG_NOSIGNAL));
+  int flags = MSG_TRUNC | MSG_CTRUNC;
+#if defined(__linux__)
+  flags |= MSG_CMSG_CLOEXEC | MSG_NOSIGNAL;
+#endif
+
+  ssize_t rc = TEMP_FAILURE_RETRY(recvmsg(sockfd, &msg, flags));
+
   if (rc == -1) {
     return -1;
   }
@@ -111,11 +124,17 @@
     }
 
     // There isn't a macro that does the inverse of CMSG_LEN, so hack around it ourselves, with
-    // some static asserts to ensure that CMSG_LEN behaves as we expect.
-    static_assert(CMSG_LEN(0) + 1 * sizeof(int) == CMSG_LEN(1 * sizeof(int)));
-    static_assert(CMSG_LEN(0) + 2 * sizeof(int) == CMSG_LEN(2 * sizeof(int)));
-    static_assert(CMSG_LEN(0) + 3 * sizeof(int) == CMSG_LEN(3 * sizeof(int)));
-    static_assert(CMSG_LEN(0) + 4 * sizeof(int) == CMSG_LEN(4 * sizeof(int)));
+    // some asserts to ensure that CMSG_LEN behaves as we expect.
+#if defined(__linux__)
+#define CMSG_ASSERT static_assert
+#else
+// CMSG_LEN is somehow not constexpr on darwin.
+#define CMSG_ASSERT CHECK
+#endif
+    CMSG_ASSERT(CMSG_LEN(0) + 1 * sizeof(int) == CMSG_LEN(1 * sizeof(int)));
+    CMSG_ASSERT(CMSG_LEN(0) + 2 * sizeof(int) == CMSG_LEN(2 * sizeof(int)));
+    CMSG_ASSERT(CMSG_LEN(0) + 3 * sizeof(int) == CMSG_LEN(3 * sizeof(int)));
+    CMSG_ASSERT(CMSG_LEN(0) + 4 * sizeof(int) == CMSG_LEN(4 * sizeof(int)));
 
     if (cmsg->cmsg_len % sizeof(int) != 0) {
       LOG(FATAL) << "cmsg_len(" << cmsg->cmsg_len << ") not aligned to sizeof(int)";
@@ -126,6 +145,10 @@
     int* cmsg_fds = reinterpret_cast<int*>(CMSG_DATA(cmsg));
     size_t cmsg_fdcount = static_cast<size_t>(cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int);
     for (size_t i = 0; i < cmsg_fdcount; ++i) {
+#if !defined(__linux__)
+      // Linux uses MSG_CMSG_CLOEXEC instead of doing this manually.
+      fcntl(cmsg_fds[i], F_SETFD, FD_CLOEXEC);
+#endif
       received_fds.emplace_back(cmsg_fds[i]);
     }
   }
diff --git a/fs_mgr/fs_mgr_fstab.cpp b/fs_mgr/fs_mgr_fstab.cpp
index 4659add..82d9144 100644
--- a/fs_mgr/fs_mgr_fstab.cpp
+++ b/fs_mgr/fs_mgr_fstab.cpp
@@ -607,10 +607,14 @@
     return userdata;
 }
 
-void EraseFstabEntry(Fstab* fstab, const std::string& mount_point) {
+bool EraseFstabEntry(Fstab* fstab, const std::string& mount_point) {
     auto iter = std::remove_if(fstab->begin(), fstab->end(),
                                [&](const auto& entry) { return entry.mount_point == mount_point; });
-    fstab->erase(iter, fstab->end());
+    if (iter != fstab->end()) {
+        fstab->erase(iter, fstab->end());
+        return true;
+    }
+    return false;
 }
 
 void TransformFstabForGsi(Fstab* fstab) {
@@ -628,11 +632,13 @@
         userdata = BuildGsiUserdataFstabEntry();
     }
 
-    EraseFstabEntry(fstab, "/system");
-    EraseFstabEntry(fstab, "/data");
+    if (EraseFstabEntry(fstab, "/system")) {
+        fstab->emplace_back(BuildGsiSystemFstabEntry());
+    }
 
-    fstab->emplace_back(BuildGsiSystemFstabEntry());
-    fstab->emplace_back(userdata);
+    if (EraseFstabEntry(fstab, "/data")) {
+        fstab->emplace_back(userdata);
+    }
 }
 
 }  // namespace
diff --git a/init/property_service.cpp b/init/property_service.cpp
index 46e5e12..76638b8 100644
--- a/init/property_service.cpp
+++ b/init/property_service.cpp
@@ -908,6 +908,13 @@
             LoadPropertyInfoFromFile("/vendor/etc/selinux/nonplat_property_contexts",
                                      &property_infos);
         }
+        if (access("/product/etc/selinux/product_property_contexts", R_OK) != -1) {
+            LoadPropertyInfoFromFile("/product/etc/selinux/product_property_contexts",
+                                     &property_infos);
+        }
+        if (access("/odm/etc/selinux/odm_property_contexts", R_OK) != -1) {
+            LoadPropertyInfoFromFile("/odm/etc/selinux/odm_property_contexts", &property_infos);
+        }
     } else {
         if (!LoadPropertyInfoFromFile("/plat_property_contexts", &property_infos)) {
             return;
@@ -916,6 +923,8 @@
             // Fallback to nonplat_* if vendor_* doesn't exist.
             LoadPropertyInfoFromFile("/nonplat_property_contexts", &property_infos);
         }
+        LoadPropertyInfoFromFile("/product_property_contexts", &property_infos);
+        LoadPropertyInfoFromFile("/odm_property_contexts", &property_infos);
     }
 
     auto serialized_contexts = std::string();