Merge "Base: Check severity in destructor"
diff --git a/include/cutils/sockets.h b/include/cutils/sockets.h
index 783bd0b..a93c8ea 100644
--- a/include/cutils/sockets.h
+++ b/include/cutils/sockets.h
@@ -18,6 +18,7 @@
 #define __CUTILS_SOCKETS_H
 
 #include <errno.h>
+#include <limits.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -51,28 +52,8 @@
  * android_get_control_socket - simple helper function to get the file
  * descriptor of our init-managed Unix domain socket. `name' is the name of the
  * socket, as given in init.rc. Returns -1 on error.
- *
- * This is inline and not in libcutils proper because we want to use this in
- * third-party daemons with minimal modification.
  */
-static inline int android_get_control_socket(const char* name)
-{
-	char key[64];
-	snprintf(key, sizeof(key), ANDROID_SOCKET_ENV_PREFIX "%s", name);
-
-	const char* val = getenv(key);
-	if (!val) {
-		return -1;
-	}
-
-	errno = 0;
-	int fd = strtol(val, NULL, 10);
-	if (errno) {
-		return -1;
-	}
-
-	return fd;
-}
+int android_get_control_socket(const char* name);
 
 /*
  * See also android.os.LocalSocketAddress.Namespace
diff --git a/include/utils/Flattenable.h b/include/utils/Flattenable.h
index 882a8b2..c37ac60 100644
--- a/include/utils/Flattenable.h
+++ b/include/utils/Flattenable.h
@@ -19,10 +19,13 @@
 
 
 #include <stdint.h>
+#include <string.h>
 #include <sys/types.h>
 #include <utils/Errors.h>
 #include <utils/Debug.h>
 
+#include <type_traits>
+
 namespace android {
 
 
@@ -60,14 +63,18 @@
     // write a POD structure
     template<typename T>
     static void write(void*& buffer, size_t& size, const T& value) {
-        *static_cast<T*>(buffer) = value;
+        static_assert(std::is_trivially_copyable<T>::value,
+                      "Cannot flatten a non-trivially-copyable type");
+        memcpy(buffer, &value, sizeof(T));
         advance(buffer, size, sizeof(T));
     }
 
     // read a POD structure
     template<typename T>
     static void read(void const*& buffer, size_t& size, T& value) {
-        value = *static_cast<T const*>(buffer);
+        static_assert(std::is_trivially_copyable<T>::value,
+                      "Cannot unflatten a non-trivially-copyable type");
+        memcpy(&value, buffer, sizeof(T));
         advance(buffer, size, sizeof(T));
     }
 };
diff --git a/libcutils/fs_config.c b/libcutils/fs_config.c
index 2922ec4..0b0e2c7 100644
--- a/libcutils/fs_config.c
+++ b/libcutils/fs_config.c
@@ -146,6 +146,9 @@
     { 00755, AID_WIFI,      AID_WIFI,     CAP_MASK_LONG(CAP_NET_ADMIN) |
                                           CAP_MASK_LONG(CAP_NET_RAW),    "system/bin/hostapd" },
 
+    /* Support wifi_hal_legacy administering a network interface. */
+    { 00755, AID_WIFI,      AID_WIFI,     CAP_MASK_LONG(CAP_NET_ADMIN) | CAP_MASK_LONG(CAP_NET_RAW),    "system/bin/hw/wifi_hal_legacy" },
+
     { 00750, AID_ROOT,      AID_ROOT,      0, "system/bin/uncrypt" },
     { 00750, AID_ROOT,      AID_ROOT,      0, "system/bin/install-recovery.sh" },
     { 00755, AID_ROOT,      AID_SHELL,     0, "system/bin/*" },
diff --git a/libcutils/sockets.cpp b/libcutils/sockets.cpp
index d9ab146..bba63ac 100644
--- a/libcutils/sockets.cpp
+++ b/libcutils/sockets.cpp
@@ -45,3 +45,24 @@
     }
     return -1;
 }
+
+int android_get_control_socket(const char* name) {
+    char key[64];
+    snprintf(key, sizeof(key), ANDROID_SOCKET_ENV_PREFIX "%s", name);
+
+    const char* val = getenv(key);
+    if (!val) {
+        return -1;
+    }
+
+    errno = 0;
+    long ret = strtol(val, NULL, 10);
+    if (errno) {
+        return -1;
+    }
+    if (ret < 0 || ret > INT_MAX) {
+        return -1;
+    }
+
+    return static_cast<int>(ret);
+}
diff --git a/lmkd/Android.mk b/lmkd/Android.mk
index 8c88661..8980d1c 100644
--- a/lmkd/Android.mk
+++ b/lmkd/Android.mk
@@ -2,7 +2,7 @@
 include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES := lmkd.c
-LOCAL_SHARED_LIBRARIES := liblog libm libc libprocessgroup
+LOCAL_SHARED_LIBRARIES := liblog libm libc libprocessgroup libcutils
 LOCAL_CFLAGS := -Werror
 
 LOCAL_MODULE := lmkd