Merge "Always explain why bind(2) failed."
diff --git a/adb/Android.mk b/adb/Android.mk
index 85d1730..6951904 100644
--- a/adb/Android.mk
+++ b/adb/Android.mk
@@ -5,7 +5,11 @@
 
 LOCAL_PATH:= $(call my-dir)
 
-ADB_CLANG := true
+ifeq ($(HOST_OS),windows)
+  adb_host_clang := false  # libc++ for mingw not ready yet.
+else
+  adb_host_clang := true
+endif
 
 # libadb
 # =========================================================
@@ -27,6 +31,11 @@
     transport_local.cpp \
     transport_usb.cpp \
 
+LIBADB_TEST_SRCS := \
+    adb_io_test.cpp \
+    adb_utils_test.cpp \
+    transport_test.cpp \
+
 LIBADB_CFLAGS := \
     -Wall -Werror \
     -Wno-unused-parameter \
@@ -65,7 +74,7 @@
 include $(BUILD_STATIC_LIBRARY)
 
 include $(CLEAR_VARS)
-LOCAL_CLANG := $(ADB_CLANG)
+LOCAL_CLANG := $(adb_host_clang)
 LOCAL_MODULE := libadb
 LOCAL_CFLAGS := $(LIBADB_CFLAGS) -DADB_HOST=1
 LOCAL_SRC_FILES := \
@@ -85,13 +94,8 @@
 
 include $(BUILD_HOST_STATIC_LIBRARY)
 
-LIBADB_TEST_SRCS := \
-    adb_io_test.cpp \
-    adb_utils_test.cpp \
-    transport_test.cpp \
-
 include $(CLEAR_VARS)
-LOCAL_CLANG := $(ADB_CLANG)
+LOCAL_CLANG := true
 LOCAL_MODULE := adbd_test
 LOCAL_CFLAGS := -DADB_HOST=0 $(LIBADB_CFLAGS)
 LOCAL_SRC_FILES := $(LIBADB_TEST_SRCS)
@@ -100,7 +104,7 @@
 include $(BUILD_NATIVE_TEST)
 
 include $(CLEAR_VARS)
-LOCAL_CLANG := $(ADB_CLANG)
+LOCAL_CLANG := $(adb_host_clang)
 LOCAL_MODULE := adb_test
 LOCAL_CFLAGS := -DADB_HOST=1 $(LIBADB_CFLAGS)
 LOCAL_SRC_FILES := $(LIBADB_TEST_SRCS) services.cpp
@@ -135,15 +139,11 @@
 endif
 
 ifeq ($(HOST_OS),windows)
+  LOCAL_LDLIBS += -lws2_32 -lgdi32
   EXTRA_STATIC_LIBS := AdbWinApi
-  ifneq ($(strip $(USE_MINGW)),)
-    # MinGW under Linux case
-    LOCAL_LDLIBS += -lws2_32 -lgdi32
-    USE_SYSDEPS_WIN32 := 1
-  endif
 endif
 
-LOCAL_CLANG := $(ADB_CLANG)
+LOCAL_CLANG := $(adb_host_clang)
 
 LOCAL_SRC_FILES := \
     adb_main.cpp \
@@ -166,12 +166,19 @@
     libadb \
     libbase \
     libcrypto_static \
+    libcutils \
     $(EXTRA_STATIC_LIBS) \
 
-ifeq ($(USE_SYSDEPS_WIN32),)
-    LOCAL_STATIC_LIBRARIES += libcutils
+# libc++ not available on windows yet
+ifneq ($(HOST_OS),windows)
+    LOCAL_CXX_STL := libc++_static
 endif
 
+# Don't add anything here, we don't want additional shared dependencies
+# on the host adb tool, and shared libraries that link against libc++
+# will violate ODR
+LOCAL_SHARED_LIBRARIES :=
+
 include $(BUILD_HOST_EXECUTABLE)
 
 $(call dist-for-goals,dist_files sdk,$(LOCAL_BUILT_MODULE))
@@ -188,7 +195,7 @@
 
 include $(CLEAR_VARS)
 
-LOCAL_CLANG := $(ADB_CLANG)
+LOCAL_CLANG := true
 
 LOCAL_SRC_FILES := \
     adb_main.cpp \
diff --git a/adb/adb_utils.cpp b/adb/adb_utils.cpp
index b515f59..f10c143 100644
--- a/adb/adb_utils.cpp
+++ b/adb/adb_utils.cpp
@@ -21,6 +21,8 @@
 #include <sys/types.h>
 #include <unistd.h>
 
+#include "sysdeps.h"
+
 bool getcwd(std::string* s) {
   char* cwd = getcwd(nullptr, 0);
   if (cwd != nullptr) *s = cwd;
@@ -33,19 +35,18 @@
   return lstat(path.c_str(), &sb) != -1 && S_ISDIR(sb.st_mode);
 }
 
-static bool should_escape(const char c) {
-  return (c == ' ' || c == '\'' || c == '"' || c == '\\' || c == '(' || c == ')');
-}
-
 std::string escape_arg(const std::string& s) {
-  // Preserve empty arguments.
-  if (s.empty()) return "\"\"";
+  std::string result = s;
 
-  std::string result(s);
+  // Insert a \ before any ' in the string.
   for (auto it = result.begin(); it != result.end(); ++it) {
-      if (should_escape(*it)) {
+      if (*it == '\'') {
           it = result.insert(it, '\\') + 1;
       }
   }
+
+  // Prefix and suffix the whole string with '.
+  result.insert(result.begin(), '\'');
+  result.push_back('\'');
   return result;
 }
diff --git a/adb/adb_utils_test.cpp b/adb/adb_utils_test.cpp
index 95e28a8..a395079 100644
--- a/adb/adb_utils_test.cpp
+++ b/adb/adb_utils_test.cpp
@@ -25,28 +25,28 @@
 }
 
 TEST(adb_utils, escape_arg) {
-  ASSERT_EQ(R"("")", escape_arg(""));
+  ASSERT_EQ(R"('')", escape_arg(""));
 
-  ASSERT_EQ(R"(abc)", escape_arg("abc"));
+  ASSERT_EQ(R"('abc')", escape_arg("abc"));
 
-  ASSERT_EQ(R"(\ abc)", escape_arg(" abc"));
-  ASSERT_EQ(R"(\'abc)", escape_arg("'abc"));
-  ASSERT_EQ(R"(\"abc)", escape_arg("\"abc"));
-  ASSERT_EQ(R"(\\abc)", escape_arg("\\abc"));
-  ASSERT_EQ(R"(\(abc)", escape_arg("(abc"));
-  ASSERT_EQ(R"(\)abc)", escape_arg(")abc"));
+  ASSERT_EQ(R"(' abc')", escape_arg(" abc"));
+  ASSERT_EQ(R"('\'abc')", escape_arg("'abc"));
+  ASSERT_EQ(R"('"abc')", escape_arg("\"abc"));
+  ASSERT_EQ(R"('\abc')", escape_arg("\\abc"));
+  ASSERT_EQ(R"('(abc')", escape_arg("(abc"));
+  ASSERT_EQ(R"(')abc')", escape_arg(")abc"));
 
-  ASSERT_EQ(R"(abc\ abc)", escape_arg("abc abc"));
-  ASSERT_EQ(R"(abc\'abc)", escape_arg("abc'abc"));
-  ASSERT_EQ(R"(abc\"abc)", escape_arg("abc\"abc"));
-  ASSERT_EQ(R"(abc\\abc)", escape_arg("abc\\abc"));
-  ASSERT_EQ(R"(abc\(abc)", escape_arg("abc(abc"));
-  ASSERT_EQ(R"(abc\)abc)", escape_arg("abc)abc"));
+  ASSERT_EQ(R"('abc abc')", escape_arg("abc abc"));
+  ASSERT_EQ(R"('abc\'abc')", escape_arg("abc'abc"));
+  ASSERT_EQ(R"('abc"abc')", escape_arg("abc\"abc"));
+  ASSERT_EQ(R"('abc\abc')", escape_arg("abc\\abc"));
+  ASSERT_EQ(R"('abc(abc')", escape_arg("abc(abc"));
+  ASSERT_EQ(R"('abc)abc')", escape_arg("abc)abc"));
 
-  ASSERT_EQ(R"(abc\ )", escape_arg("abc "));
-  ASSERT_EQ(R"(abc\')", escape_arg("abc'"));
-  ASSERT_EQ(R"(abc\")", escape_arg("abc\""));
-  ASSERT_EQ(R"(abc\\)", escape_arg("abc\\"));
-  ASSERT_EQ(R"(abc\()", escape_arg("abc("));
-  ASSERT_EQ(R"(abc\))", escape_arg("abc)"));
+  ASSERT_EQ(R"('abc ')", escape_arg("abc "));
+  ASSERT_EQ(R"('abc\'')", escape_arg("abc'"));
+  ASSERT_EQ(R"('abc"')", escape_arg("abc\""));
+  ASSERT_EQ(R"('abc\')", escape_arg("abc\\"));
+  ASSERT_EQ(R"('abc(')", escape_arg("abc("));
+  ASSERT_EQ(R"('abc)')", escape_arg("abc)"));
 }
diff --git a/adb/commandline.cpp b/adb/commandline.cpp
index 2d41050..f193d2f 100644
--- a/adb/commandline.cpp
+++ b/adb/commandline.cpp
@@ -1735,7 +1735,11 @@
         return 1;
     }
 
+#if defined(_WIN32) // Remove when we're using clang for Win32.
+    std::string cmd = android::base::StringPrintf("exec:pm install-create -S %u", (unsigned) total_size);
+#else
     std::string cmd = android::base::StringPrintf("exec:pm install-create -S %" PRIu64, total_size);
+#endif
     for (i = 1; i < first_apk; i++) {
         cmd += " " + escape_arg(argv[i]);
     }
@@ -1775,9 +1779,15 @@
             goto finalize_session;
         }
 
+#if defined(_WIN32) // Remove when we're using clang for Win32.
+        std::string cmd = android::base::StringPrintf(
+                "exec:pm install-write -S %u %d %d_%s -",
+                (unsigned) sb.st_size, session_id, i, get_basename(file));
+#else
         std::string cmd = android::base::StringPrintf(
                 "exec:pm install-write -S %" PRIu64 " %d %d_%s -",
                 static_cast<uint64_t>(sb.st_size), session_id, i, get_basename(file));
+#endif
 
         int localFd = adb_open(file, O_RDONLY);
         if (localFd < 0) {
diff --git a/fastboot/Android.mk b/fastboot/Android.mk
index b9e957f..7b2975b 100644
--- a/fastboot/Android.mk
+++ b/fastboot/Android.mk
@@ -74,6 +74,16 @@
 LOCAL_STATIC_LIBRARIES += libf2fs_utils_host libf2fs_ioutils_host libf2fs_dlutils_host
 endif
 
+# libc++ not available on windows yet
+ifneq ($(HOST_OS),windows)
+    LOCAL_CXX_STL := libc++_static
+endif
+
+# Don't add anything here, we don't want additional shared dependencies
+# on the host fastboot tool, and shared libraries that link against libc++
+# will violate ODR
+LOCAL_SHARED_LIBRARIES :=
+
 include $(BUILD_HOST_EXECUTABLE)
 
 my_dist_files := $(LOCAL_BUILT_MODULE)
diff --git a/include/cutils/partition_utils.h b/include/cutils/partition_utils.h
index 597df92..72ca80d 100644
--- a/include/cutils/partition_utils.h
+++ b/include/cutils/partition_utils.h
@@ -20,7 +20,6 @@
 __BEGIN_DECLS
 
 int partition_wiped(char *source);
-void erase_footer(const char *dev_path, long long size);
 
 __END_DECLS
 
diff --git a/libziparchive/zip_archive.cc b/libziparchive/zip_archive.cc
index 57c46a3..8582344 100644
--- a/libziparchive/zip_archive.cc
+++ b/libziparchive/zip_archive.cc
@@ -1131,7 +1131,22 @@
     return kIoError;
   }
 
-  int result = TEMP_FAILURE_RETRY(ftruncate(fd, declared_length + current_offset));
+  int result = 0;
+#if defined(__linux__)
+  // Make sure we have enough space on the volume to extract the compressed
+  // entry. Note that the call to ftruncate below will change the file size but
+  // will not allocate space on disk.
+  if (declared_length > 0) {
+    result = TEMP_FAILURE_RETRY(fallocate(fd, 0, current_offset, declared_length));
+    if (result == -1) {
+      ALOGW("Zip: unable to allocate space for file to %" PRId64 ": %s",
+            static_cast<int64_t>(declared_length + current_offset), strerror(errno));
+      return kIoError;
+    }
+  }
+#endif  // defined(__linux__)
+
+  result = TEMP_FAILURE_RETRY(ftruncate(fd, declared_length + current_offset));
   if (result == -1) {
     ALOGW("Zip: unable to truncate file to %" PRId64 ": %s",
           static_cast<int64_t>(declared_length + current_offset), strerror(errno));
diff --git a/logd/LogBuffer.cpp b/logd/LogBuffer.cpp
index a0436ef..1859461 100644
--- a/logd/LogBuffer.cpp
+++ b/logd/LogBuffer.cpp
@@ -226,6 +226,68 @@
     return it;
 }
 
+// Define a temporary mechanism to report the last LogBufferElement pointer
+// for the specified uid, pid and tid. Used below to help merge-sort when
+// pruning for worst UID.
+class LogBufferElementKey {
+    const union {
+        struct {
+            uint16_t uid;
+            uint16_t pid;
+            uint16_t tid;
+            uint16_t padding;
+        } __packed;
+        uint64_t value;
+    } __packed;
+
+public:
+    LogBufferElementKey(uid_t u, pid_t p, pid_t t):uid(u),pid(p),tid(t),padding(0) { }
+    LogBufferElementKey(uint64_t k):value(k) { }
+
+    uint64_t getKey() { return value; }
+};
+
+struct LogBufferElementEntry {
+    const uint64_t key;
+    LogBufferElement *last;
+
+public:
+    LogBufferElementEntry(const uint64_t &k, LogBufferElement *e):key(k),last(e) { }
+
+    const uint64_t&getKey() const { return key; }
+
+    LogBufferElement *getLast() { return last; }
+};
+
+struct LogBufferElementLast : public android::BasicHashtable<uint64_t, LogBufferElementEntry> {
+
+    bool merge(LogBufferElement *e, unsigned short dropped) {
+        LogBufferElementKey key(e->getUid(), e->getPid(), e->getTid());
+        android::hash_t hash = android::hash_type(key.getKey());
+        ssize_t index = find(-1, hash, key.getKey());
+        if (index != -1) {
+            LogBufferElementEntry &entry = editEntryAt(index);
+            LogBufferElement *l = entry.getLast();
+            unsigned short d = l->getDropped();
+            if ((dropped + d) > USHRT_MAX) {
+                removeAt(index);
+            } else {
+                l->setDropped(dropped + d);
+                return true;
+            }
+        }
+        return false;
+    }
+
+    size_t add(LogBufferElement *e) {
+        LogBufferElementKey key(e->getUid(), e->getPid(), e->getTid());
+        android::hash_t hash = android::hash_type(key.getKey());
+        return android::BasicHashtable<uint64_t, LogBufferElementEntry>::
+            add(hash, LogBufferElementEntry(key.getKey(), e));
+    }
+
+};
+
 // prune "pruneRows" of type "id" from the buffer.
 //
 // mLogElementsLock must be held when this function is called.
@@ -301,7 +363,7 @@
 
         bool kick = false;
         bool leading = true;
-        LogBufferElement *last = NULL;
+        LogBufferElementLast last;
         for(it = mLogElements.begin(); it != mLogElements.end();) {
             LogBufferElement *e = *it;
 
@@ -322,24 +384,18 @@
                 continue;
             }
 
-            pid_t pid = e->getPid();
-
             // merge any drops
-            if (last && dropped
-             && ((dropped + last->getDropped()) < USHRT_MAX)
-             && (last->getPid() == pid)
-             && (last->getTid() == e->getTid())) {
+            if (dropped && last.merge(e, dropped)) {
                 it = mLogElements.erase(it);
                 stats.erase(e);
                 delete e;
-                last->setDropped(dropped + last->getDropped());
                 continue;
             }
 
             leading = false;
 
             if (hasBlacklist && mPrune.naughty(e)) {
-                last = NULL;
+                last.clear();
                 it = erase(it);
                 if (dropped) {
                     continue;
@@ -361,13 +417,13 @@
             }
 
             if (dropped) {
-                last = e;
+                last.add(e);
                 ++it;
                 continue;
             }
 
             if (e->getUid() != worst) {
-                last = NULL;
+                last.clear();
                 ++it;
                 continue;
             }
@@ -382,17 +438,12 @@
             unsigned short len = e->getMsgLen();
             stats.drop(e);
             e->setDropped(1);
-            // merge any drops
-            if (last
-             && (last->getDropped() < (USHRT_MAX - 1))
-             && (last->getPid() == pid)
-             && (last->getTid() == e->getTid())) {
+            if (last.merge(e, 1)) {
                 it = mLogElements.erase(it);
                 stats.erase(e);
                 delete e;
-                last->setDropped(last->getDropped() + 1);
             } else {
-                last = e;
+                last.add(e);
                 ++it;
             }
             if (worst_sizes < second_worst_sizes) {
@@ -400,6 +451,7 @@
             }
             worst_sizes -= len;
         }
+        last.clear();
 
         if (!kick || !mPrune.worstUidEnabled()) {
             break; // the following loop will ask bad clients to skip/drop
diff --git a/rootdir/init.rc b/rootdir/init.rc
index a2b8f59..a5ea60a 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -248,6 +248,7 @@
     mkdir /data/misc/bluedroid 0770 bluetooth net_bt_stack
     mkdir /data/misc/bluetooth 0770 system system
     mkdir /data/misc/keystore 0700 keystore keystore
+    mkdir /data/misc/gatekeeper 0700 system system
     mkdir /data/misc/keychain 0771 system system
     mkdir /data/misc/net 0750 root shell
     mkdir /data/misc/radio 0770 system radio