Merge "adb: fix mkdirs test."
diff --git a/base/Android.mk b/base/Android.mk
index d20a81f..1693e74 100644
--- a/base/Android.mk
+++ b/base/Android.mk
@@ -67,7 +67,7 @@
 LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
 LOCAL_CPPFLAGS := $(libbase_cppflags) $(libbase_linux_cppflags)
 LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
-LOCAL_STATIC_LIBRARIES := libcutils
+LOCAL_STATIC_LIBRARIES := liblog
 LOCAL_MULTILIB := both
 include $(BUILD_STATIC_LIBRARY)
 
@@ -77,7 +77,6 @@
 LOCAL_WHOLE_STATIC_LIBRARIES := libbase
 LOCAL_SHARED_LIBRARIES := liblog
 LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
-LOCAL_SHARED_LIBRARIES := libcutils
 LOCAL_MULTILIB := both
 include $(BUILD_SHARED_LIBRARY)
 
@@ -94,7 +93,7 @@
 LOCAL_CPPFLAGS_darwin := $(libbase_darwin_cppflags)
 LOCAL_CPPFLAGS_linux := $(libbase_linux_cppflags)
 LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
-LOCAL_STATIC_LIBRARIES := libcutils
+LOCAL_STATIC_LIBRARIES := liblog
 LOCAL_MULTILIB := both
 LOCAL_MODULE_HOST_OS := darwin linux windows
 include $(BUILD_HOST_STATIC_LIBRARY)
@@ -104,7 +103,6 @@
 LOCAL_WHOLE_STATIC_LIBRARIES := libbase
 LOCAL_SHARED_LIBRARIES := liblog
 LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
-LOCAL_STATIC_LIBRARIES := libcutils
 LOCAL_MULTILIB := both
 LOCAL_MODULE_HOST_OS := darwin linux windows
 include $(BUILD_HOST_SHARED_LIBRARY)
diff --git a/base/file.cpp b/base/file.cpp
index bcdfc5e..da1adba 100644
--- a/base/file.cpp
+++ b/base/file.cpp
@@ -29,10 +29,6 @@
 #include "cutils/log.h"
 #include "utils/Compat.h"
 
-#if !defined(_WIN32)
-#define O_BINARY 0
-#endif
-
 namespace android {
 namespace base {
 
diff --git a/base/include/android-base/file.h b/base/include/android-base/file.h
index 486befc..5342d98 100644
--- a/base/include/android-base/file.h
+++ b/base/include/android-base/file.h
@@ -20,6 +20,10 @@
 #include <sys/stat.h>
 #include <string>
 
+#if !defined(_WIN32) && !defined(O_BINARY)
+#define O_BINARY 0
+#endif
+
 namespace android {
 namespace base {
 
diff --git a/base/logging.cpp b/base/logging.cpp
index a385902..1741871 100644
--- a/base/logging.cpp
+++ b/base/logging.cpp
@@ -68,7 +68,13 @@
 #include <windows.h>
 #endif
 
-static pid_t GetThreadId() {
+#if defined(_WIN32)
+typedef uint32_t thread_id;
+#else
+typedef pid_t thread_id;
+#endif
+
+static thread_id GetThreadId() {
 #if defined(__BIONIC__)
   return gettid();
 #elif defined(__APPLE__)
diff --git a/debuggerd/tombstone.cpp b/debuggerd/tombstone.cpp
index dda6677..7cf2ffc 100644
--- a/debuggerd/tombstone.cpp
+++ b/debuggerd/tombstone.cpp
@@ -134,8 +134,15 @@
       switch (code) {
         case SEGV_MAPERR: return "SEGV_MAPERR";
         case SEGV_ACCERR: return "SEGV_ACCERR";
+#if defined(SEGV_BNDERR)
+        case SEGV_BNDERR: return "SEGV_BNDERR";
+#endif
       }
+#if defined(SEGV_BNDERR)
+      static_assert(NSIGSEGV == SEGV_BNDERR, "missing SEGV_* si_code");
+#else
       static_assert(NSIGSEGV == SEGV_ACCERR, "missing SEGV_* si_code");
+#endif
       break;
     case SIGTRAP:
       switch (code) {
diff --git a/fastboot/socket.cpp b/fastboot/socket.cpp
index d49f47f..14ecd93 100644
--- a/fastboot/socket.cpp
+++ b/fastboot/socket.cpp
@@ -48,18 +48,6 @@
     return ret;
 }
 
-bool Socket::SetReceiveTimeout(int timeout_ms) {
-    if (timeout_ms != receive_timeout_ms_) {
-        if (socket_set_receive_timeout(sock_, timeout_ms) == 0) {
-            receive_timeout_ms_ = timeout_ms;
-            return true;
-        }
-        return false;
-    }
-
-    return true;
-}
-
 ssize_t Socket::ReceiveAll(void* data, size_t length, int timeout_ms) {
     size_t total = 0;
 
@@ -82,6 +70,40 @@
     return socket_get_local_port(sock_);
 }
 
+// According to Windows setsockopt() documentation, if a Windows socket times out during send() or
+// recv() the state is indeterminate and should not be used. Our UDP protocol relies on being able
+// to re-send after a timeout, so we must use select() rather than SO_RCVTIMEO.
+// See https://msdn.microsoft.com/en-us/library/windows/desktop/ms740476(v=vs.85).aspx.
+bool Socket::WaitForRecv(int timeout_ms) {
+    receive_timed_out_ = false;
+
+    // In our usage |timeout_ms| <= 0 means block forever, so just return true immediately and let
+    // the subsequent recv() do the blocking.
+    if (timeout_ms <= 0) {
+        return true;
+    }
+
+    // select() doesn't always check this case and will block for |timeout_ms| if we let it.
+    if (sock_ == INVALID_SOCKET) {
+        return false;
+    }
+
+    fd_set read_set;
+    FD_ZERO(&read_set);
+    FD_SET(sock_, &read_set);
+
+    timeval timeout;
+    timeout.tv_sec = timeout_ms / 1000;
+    timeout.tv_usec = (timeout_ms % 1000) * 1000;
+
+    int result = TEMP_FAILURE_RETRY(select(sock_ + 1, &read_set, nullptr, nullptr, &timeout));
+
+    if (result == 0) {
+        receive_timed_out_ = true;
+    }
+    return result == 1;
+}
+
 // Implements the Socket interface for UDP.
 class UdpSocket : public Socket {
   public:
@@ -127,7 +149,7 @@
 }
 
 ssize_t UdpSocket::Receive(void* data, size_t length, int timeout_ms) {
-    if (!SetReceiveTimeout(timeout_ms)) {
+    if (!WaitForRecv(timeout_ms)) {
         return -1;
     }
 
@@ -206,7 +228,7 @@
 }
 
 ssize_t TcpSocket::Receive(void* data, size_t length, int timeout_ms) {
-    if (!SetReceiveTimeout(timeout_ms)) {
+    if (!WaitForRecv(timeout_ms)) {
         return -1;
     }
 
diff --git a/fastboot/socket.h b/fastboot/socket.h
index c0bd7c9..de543db 100644
--- a/fastboot/socket.h
+++ b/fastboot/socket.h
@@ -81,13 +81,17 @@
     virtual bool Send(std::vector<cutils_socket_buffer_t> buffers) = 0;
 
     // Waits up to |timeout_ms| to receive up to |length| bytes of data. |timout_ms| of 0 will
-    // block forever. Returns the number of bytes received or -1 on error/timeout. On timeout
-    // errno will be set to EAGAIN or EWOULDBLOCK.
+    // block forever. Returns the number of bytes received or -1 on error/timeout; see
+    // ReceiveTimedOut() to distinguish between the two.
     virtual ssize_t Receive(void* data, size_t length, int timeout_ms) = 0;
 
     // Calls Receive() until exactly |length| bytes have been received or an error occurs.
     virtual ssize_t ReceiveAll(void* data, size_t length, int timeout_ms);
 
+    // Returns true if the last Receive() call timed out normally and can be retried; fatal errors
+    // or successful reads will return false.
+    bool ReceiveTimedOut() { return receive_timed_out_; }
+
     // Closes the socket. Returns 0 on success, -1 on error.
     virtual int Close();
 
@@ -102,10 +106,13 @@
     // Protected constructor to force factory function use.
     Socket(cutils_socket_t sock);
 
-    // Update the socket receive timeout if necessary.
-    bool SetReceiveTimeout(int timeout_ms);
+    // Blocks up to |timeout_ms| until a read is possible on |sock_|, and sets |receive_timed_out_|
+    // as appropriate to help distinguish between normal timeouts and fatal errors. Returns true if
+    // a subsequent recv() on |sock_| will complete without blocking or if |timeout_ms| <= 0.
+    bool WaitForRecv(int timeout_ms);
 
     cutils_socket_t sock_ = INVALID_SOCKET;
+    bool receive_timed_out_ = false;
 
     // Non-class functions we want to override during tests to verify functionality. Implementation
     // should call this rather than using socket_send_buffers() directly.
@@ -113,8 +120,6 @@
             socket_send_buffers_function_ = &socket_send_buffers;
 
   private:
-    int receive_timeout_ms_ = 0;
-
     FRIEND_TEST(SocketTest, TestTcpSendBuffers);
     FRIEND_TEST(SocketTest, TestUdpSendBuffers);
 
diff --git a/fastboot/socket_mock.cpp b/fastboot/socket_mock.cpp
index c962f30..2531b53 100644
--- a/fastboot/socket_mock.cpp
+++ b/fastboot/socket_mock.cpp
@@ -55,7 +55,7 @@
         return false;
     }
 
-    bool return_value = events_.front().return_value;
+    bool return_value = events_.front().status;
     events_.pop();
     return return_value;
 }
@@ -76,21 +76,28 @@
         return -1;
     }
 
-    if (events_.front().type != EventType::kReceive) {
+    const Event& event = events_.front();
+    if (event.type != EventType::kReceive) {
         ADD_FAILURE() << "Receive() was called out-of-order";
         return -1;
     }
 
-    if (events_.front().return_value > static_cast<ssize_t>(length)) {
-        ADD_FAILURE() << "Receive(): not enough bytes (" << length << ") for "
-                      << events_.front().message;
+    const std::string& message = event.message;
+    if (message.length() > length) {
+        ADD_FAILURE() << "Receive(): not enough bytes (" << length << ") for " << message;
         return -1;
     }
 
-    ssize_t return_value = events_.front().return_value;
-    if (return_value > 0) {
-        memcpy(data, events_.front().message.data(), return_value);
+    receive_timed_out_ = event.status;
+    ssize_t return_value = message.length();
+
+    // Empty message indicates failure.
+    if (message.empty()) {
+        return_value = -1;
+    } else {
+        memcpy(data, message.data(), message.length());
     }
+
     events_.pop();
     return return_value;
 }
@@ -124,18 +131,21 @@
 }
 
 void SocketMock::AddReceive(std::string message) {
-    ssize_t return_value = message.length();
-    events_.push(Event(EventType::kReceive, std::move(message), return_value, nullptr));
+    events_.push(Event(EventType::kReceive, std::move(message), false, nullptr));
+}
+
+void SocketMock::AddReceiveTimeout() {
+    events_.push(Event(EventType::kReceive, "", true, nullptr));
 }
 
 void SocketMock::AddReceiveFailure() {
-    events_.push(Event(EventType::kReceive, "", -1, nullptr));
+    events_.push(Event(EventType::kReceive, "", false, nullptr));
 }
 
 void SocketMock::AddAccept(std::unique_ptr<Socket> sock) {
-    events_.push(Event(EventType::kAccept, "", 0, std::move(sock)));
+    events_.push(Event(EventType::kAccept, "", false, std::move(sock)));
 }
 
-SocketMock::Event::Event(EventType _type, std::string _message, ssize_t _return_value,
+SocketMock::Event::Event(EventType _type, std::string _message, ssize_t _status,
                          std::unique_ptr<Socket> _sock)
-        : type(_type), message(_message), return_value(_return_value), sock(std::move(_sock)) {}
+        : type(_type), message(_message), status(_status), sock(std::move(_sock)) {}
diff --git a/fastboot/socket_mock.h b/fastboot/socket_mock.h
index 41fe06d..eacd6bb 100644
--- a/fastboot/socket_mock.h
+++ b/fastboot/socket_mock.h
@@ -71,7 +71,10 @@
     // Adds data to provide for Receive().
     void AddReceive(std::string message);
 
-    // Adds a Receive() failure.
+    // Adds a Receive() timeout after which ReceiveTimedOut() will return true.
+    void AddReceiveTimeout();
+
+    // Adds a Receive() failure after which ReceiveTimedOut() will return false.
     void AddReceiveFailure();
 
     // Adds a Socket to return from Accept().
@@ -81,12 +84,12 @@
     enum class EventType { kSend, kReceive, kAccept };
 
     struct Event {
-        Event(EventType _type, std::string _message, ssize_t _return_value,
+        Event(EventType _type, std::string _message, ssize_t _status,
               std::unique_ptr<Socket> _sock);
 
         EventType type;
         std::string message;
-        ssize_t return_value;
+        bool status;  // Return value for Send() or timeout status for Receive().
         std::unique_ptr<Socket> sock;
     };
 
diff --git a/fastboot/socket_test.cpp b/fastboot/socket_test.cpp
index cc71075..affbdfd 100644
--- a/fastboot/socket_test.cpp
+++ b/fastboot/socket_test.cpp
@@ -28,7 +28,8 @@
 #include <gtest/gtest-spi.h>
 #include <gtest/gtest.h>
 
-enum { kTestTimeoutMs = 3000 };
+static constexpr int kShortTimeoutMs = 10;
+static constexpr int kTestTimeoutMs = 3000;
 
 // Creates connected sockets |server| and |client|. Returns true on success.
 bool MakeConnectedSockets(Socket::Protocol protocol, std::unique_ptr<Socket>* server,
@@ -87,6 +88,50 @@
     }
 }
 
+TEST(SocketTest, TestReceiveTimeout) {
+    std::unique_ptr<Socket> server, client;
+    char buffer[16];
+
+    for (Socket::Protocol protocol : {Socket::Protocol::kUdp, Socket::Protocol::kTcp}) {
+        ASSERT_TRUE(MakeConnectedSockets(protocol, &server, &client));
+
+        EXPECT_EQ(-1, server->Receive(buffer, sizeof(buffer), kShortTimeoutMs));
+        EXPECT_TRUE(server->ReceiveTimedOut());
+
+        EXPECT_EQ(-1, client->Receive(buffer, sizeof(buffer), kShortTimeoutMs));
+        EXPECT_TRUE(client->ReceiveTimedOut());
+    }
+
+    // UDP will wait for timeout if the other side closes.
+    ASSERT_TRUE(MakeConnectedSockets(Socket::Protocol::kUdp, &server, &client));
+    EXPECT_EQ(0, server->Close());
+    EXPECT_EQ(-1, client->Receive(buffer, sizeof(buffer), kShortTimeoutMs));
+    EXPECT_TRUE(client->ReceiveTimedOut());
+}
+
+TEST(SocketTest, TestReceiveFailure) {
+    std::unique_ptr<Socket> server, client;
+    char buffer[16];
+
+    for (Socket::Protocol protocol : {Socket::Protocol::kUdp, Socket::Protocol::kTcp}) {
+        ASSERT_TRUE(MakeConnectedSockets(protocol, &server, &client));
+
+        EXPECT_EQ(0, server->Close());
+        EXPECT_EQ(-1, server->Receive(buffer, sizeof(buffer), kTestTimeoutMs));
+        EXPECT_FALSE(server->ReceiveTimedOut());
+
+        EXPECT_EQ(0, client->Close());
+        EXPECT_EQ(-1, client->Receive(buffer, sizeof(buffer), kTestTimeoutMs));
+        EXPECT_FALSE(client->ReceiveTimedOut());
+    }
+
+    // TCP knows right away when the other side closes and returns 0 to indicate EOF.
+    ASSERT_TRUE(MakeConnectedSockets(Socket::Protocol::kTcp, &server, &client));
+    EXPECT_EQ(0, server->Close());
+    EXPECT_EQ(0, client->Receive(buffer, sizeof(buffer), kTestTimeoutMs));
+    EXPECT_FALSE(client->ReceiveTimedOut());
+}
+
 // Tests sending and receiving large packets.
 TEST(SocketTest, TestLargePackets) {
     std::string message(1024, '\0');
@@ -290,6 +335,11 @@
 
     mock->AddReceiveFailure();
     EXPECT_FALSE(ReceiveString(mock, "foo"));
+    EXPECT_FALSE(mock->ReceiveTimedOut());
+
+    mock->AddReceiveTimeout();
+    EXPECT_FALSE(ReceiveString(mock, "foo"));
+    EXPECT_TRUE(mock->ReceiveTimedOut());
 
     mock->AddReceive("foo");
     mock->AddReceiveFailure();
diff --git a/include/utils/ThreadDefs.h b/include/utils/ThreadDefs.h
index 9711c13..ae091e4 100644
--- a/include/utils/ThreadDefs.h
+++ b/include/utils/ThreadDefs.h
@@ -29,7 +29,11 @@
 extern "C" {
 #endif
 
+#ifdef _WIN32
+typedef uint32_t android_thread_id_t;
+#else
 typedef void* android_thread_id_t;
+#endif
 
 typedef int (*android_thread_func_t)(void*);
 
diff --git a/init/service.cpp b/init/service.cpp
index 0ddc484..bdecc32 100644
--- a/init/service.cpp
+++ b/init/service.cpp
@@ -416,7 +416,7 @@
             }
         }
 
-        std::string pid_str = StringPrintf("%d", pid);
+        std::string pid_str = StringPrintf("%d", getpid());
         for (const auto& file : writepid_files_) {
             if (!WriteStringToFile(pid_str, file)) {
                 ERROR("couldn't write %s to %s: %s\n",
diff --git a/libbacktrace/UnwindMap.cpp b/libbacktrace/UnwindMap.cpp
index 879fea5..34d79f9 100644
--- a/libbacktrace/UnwindMap.cpp
+++ b/libbacktrace/UnwindMap.cpp
@@ -33,14 +33,18 @@
 // of maps using the same map cursor.
 //-------------------------------------------------------------------------
 UnwindMap::UnwindMap(pid_t pid) : BacktraceMap(pid) {
+  unw_map_cursor_clear(&map_cursor_);
 }
 
-UnwindMap::~UnwindMap() {
+UnwindMapRemote::UnwindMapRemote(pid_t pid) : UnwindMap(pid) {
+}
+
+UnwindMapRemote::~UnwindMapRemote() {
   unw_map_cursor_destroy(&map_cursor_);
   unw_map_cursor_clear(&map_cursor_);
 }
 
-bool UnwindMap::GenerateMap() {
+bool UnwindMapRemote::GenerateMap() {
   // Use the map_cursor information to construct the BacktraceMap data
   // rather than reparsing /proc/self/maps.
   unw_map_cursor_reset(&map_cursor_);
@@ -63,7 +67,7 @@
   return true;
 }
 
-bool UnwindMap::Build() {
+bool UnwindMapRemote::Build() {
   return (unw_map_cursor_create(&map_cursor_, pid_) == 0) && GenerateMap();
 }
 
@@ -84,6 +88,7 @@
   for (int i = 0; i < 3; i++) {
     maps_.clear();
 
+    // Save the map data retrieved so we can tell if it changes.
     unw_map_local_cursor_get(&map_cursor_);
 
     unw_map_t unw_map;
@@ -142,7 +147,7 @@
   } else if (pid == getpid()) {
     map = new UnwindMapLocal();
   } else {
-    map = new UnwindMap(pid);
+    map = new UnwindMapRemote(pid);
   }
   if (!map->Build()) {
     delete map;
diff --git a/libbacktrace/UnwindMap.h b/libbacktrace/UnwindMap.h
index e292016..111401f 100644
--- a/libbacktrace/UnwindMap.h
+++ b/libbacktrace/UnwindMap.h
@@ -29,29 +29,35 @@
 class UnwindMap : public BacktraceMap {
 public:
   UnwindMap(pid_t pid);
-  virtual ~UnwindMap();
-
-  virtual bool Build();
 
   unw_map_cursor_t* GetMapCursor() { return &map_cursor_; }
 
 protected:
-  virtual bool GenerateMap();
-
   unw_map_cursor_t map_cursor_;
 };
 
+class UnwindMapRemote : public UnwindMap {
+public:
+  UnwindMapRemote(pid_t pid);
+  virtual ~UnwindMapRemote();
+
+  bool Build() override;
+
+private:
+  bool GenerateMap();
+};
+
 class UnwindMapLocal : public UnwindMap {
 public:
   UnwindMapLocal();
   virtual ~UnwindMapLocal();
 
-  virtual bool Build();
+  bool Build() override;
 
-  virtual void FillIn(uintptr_t addr, backtrace_map_t* map);
+  void FillIn(uintptr_t addr, backtrace_map_t* map) override;
 
-protected:
-  virtual bool GenerateMap();
+private:
+  bool GenerateMap();
 
   bool map_created_;
 };
diff --git a/libcutils/ashmem-dev.c b/libcutils/ashmem-dev.c
index d6a48c9..4a07d66 100644
--- a/libcutils/ashmem-dev.c
+++ b/libcutils/ashmem-dev.c
@@ -118,15 +118,16 @@
     }
 
     if (rdev) {
-        ALOGE("illegal fd=%d mode=0%o rdev=%d:%d expected 0%o %d:%d",
+        LOG_ALWAYS_FATAL("illegal fd=%d mode=0%o rdev=%d:%d expected 0%o %d:%d",
           fd, st.st_mode, major(st.st_rdev), minor(st.st_rdev),
           S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IRGRP,
           major(rdev), minor(rdev));
     } else {
-        ALOGE("illegal fd=%d mode=0%o rdev=%d:%d expected 0%o",
+        LOG_ALWAYS_FATAL("illegal fd=%d mode=0%o rdev=%d:%d expected 0%o",
           fd, st.st_mode, major(st.st_rdev), minor(st.st_rdev),
           S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IRGRP);
     }
+    /* NOTREACHED */
 
     errno = ENOTTY;
     return -1;
diff --git a/libcutils/str_parms.c b/libcutils/str_parms.c
index 4f23d09..8dafded 100644
--- a/libcutils/str_parms.c
+++ b/libcutils/str_parms.c
@@ -31,6 +31,20 @@
 
 #define UNUSED __attribute__((unused))
 
+/* When an object is allocated but not freed in a function,
+ * because its ownership is released to other object like a hashmap,
+ * call RELEASE_OWNERSHIP to tell the clang analyzer and avoid
+ * false warnings about potential memory leak.
+ * For now, a "temporary" assignment to global variables
+ * is enough to confuse the clang static analyzer.
+ */
+#ifdef __clang_analyzer__
+static void *released_pointer;
+#define RELEASE_OWNERSHIP(x) { released_pointer = x; released_pointer = 0; }
+#else
+#define RELEASE_OWNERSHIP(x)
+#endif
+
 struct str_parms {
     Hashmap *map;
 };
@@ -170,9 +184,12 @@
 
         /* if we replaced a value, free it */
         old_val = hashmapPut(str_parms->map, key, value);
+        RELEASE_OWNERSHIP(value);
         if (old_val) {
             free(old_val);
             free(key);
+        } else {
+            RELEASE_OWNERSHIP(key);
         }
 
         items++;
@@ -222,10 +239,13 @@
             goto clean_up;
         }
         // For new keys, hashmap takes ownership of tmp_key and tmp_val.
+        RELEASE_OWNERSHIP(tmp_key);
+        RELEASE_OWNERSHIP(tmp_val);
         tmp_key = tmp_val = NULL;
     } else {
         // For existing keys, hashmap takes ownership of tmp_val.
         // (It also gives up ownership of old_val.)
+        RELEASE_OWNERSHIP(tmp_val);
         tmp_val = NULL;
     }
 
diff --git a/liblog/fake_log_device.c b/liblog/fake_log_device.c
index cb80ee6..5f7a078 100644
--- a/liblog/fake_log_device.c
+++ b/liblog/fake_log_device.c
@@ -367,7 +367,11 @@
     char prefixBuf[128], suffixBuf[128];
     char priChar;
     time_t when;
+#if !defined(_WIN32)
     pid_t pid, tid;
+#else
+    uint32_t pid, tid;
+#endif
 
     TRACE("LOG %d: %s %s", logPrio, tag, msg);
 
diff --git a/libutils/Android.mk b/libutils/Android.mk
index 631b5a3..3663c52 100644
--- a/libutils/Android.mk
+++ b/libutils/Android.mk
@@ -22,7 +22,6 @@
 	Log.cpp \
 	NativeHandle.cpp \
 	Printer.cpp \
-	ProcessCallStack.cpp \
 	PropertyMap.cpp \
 	RefBase.cpp \
 	SharedBuffer.cpp \
@@ -44,7 +43,7 @@
 # =====================================================
 include $(CLEAR_VARS)
 LOCAL_SRC_FILES:= $(commonSources)
-LOCAL_SRC_FILES_linux := Looper.cpp
+LOCAL_SRC_FILES_linux := Looper.cpp ProcessCallStack.cpp
 LOCAL_CFLAGS_darwin := -Wno-unused-parameter
 LOCAL_MODULE:= libutils
 LOCAL_STATIC_LIBRARIES := liblog
@@ -67,6 +66,7 @@
 	$(commonSources) \
 	BlobCache.cpp \
 	Looper.cpp \
+	ProcessCallStack.cpp \
 	Trace.cpp
 
 ifeq ($(TARGET_ARCH),mips)
diff --git a/libutils/ProcessCallStack.cpp b/libutils/ProcessCallStack.cpp
index 011c302..cdb586d 100644
--- a/libutils/ProcessCallStack.cpp
+++ b/libutils/ProcessCallStack.cpp
@@ -146,7 +146,6 @@
     clear();
 
     // Get current time.
-#ifndef USE_MINGW
     {
         time_t t = time(NULL);
         struct tm tm;
@@ -199,7 +198,6 @@
         ALOGE("%s: Failed to readdir from %s: %s",
               __FUNCTION__, PATH_SELF_TASK, strerror(code));
     }
-#endif
 
     closedir(dp);
 }
diff --git a/libziparchive/Android.mk b/libziparchive/Android.mk
index 056b3e1..3cd8b87 100644
--- a/libziparchive/Android.mk
+++ b/libziparchive/Android.mk
@@ -95,13 +95,12 @@
 LOCAL_CFLAGS := $(libziparchive_common_c_flags)
 LOCAL_CPPFLAGS := -Wno-unnamed-type-template-args $(libziparchive_common_cpp_flags)
 LOCAL_SRC_FILES := $(libziparchive_test_files)
-LOCAL_SHARED_LIBRARIES := \
-    libziparchive-host \
-    liblog \
-    libbase \
-
 LOCAL_STATIC_LIBRARIES := \
-    libutils \
+    libziparchive-host \
     libz \
+    libbase \
+    libutils \
+    liblog \
 
+LOCAL_MODULE_HOST_OS := darwin linux windows
 include $(BUILD_HOST_NATIVE_TEST)
diff --git a/libziparchive/zip_archive.cc b/libziparchive/zip_archive.cc
index 3b1e972..a2d6fcc 100644
--- a/libziparchive/zip_archive.cc
+++ b/libziparchive/zip_archive.cc
@@ -224,9 +224,7 @@
           strerror(errno));
     return kIoError;
   }
-  ssize_t actual = TEMP_FAILURE_RETRY(
-      read(fd, scan_buffer, static_cast<size_t>(read_amount)));
-  if (actual != static_cast<ssize_t>(read_amount)) {
+  if (!android::base::ReadFully(fd, scan_buffer, static_cast<size_t>(read_amount))) {
     ALOGW("Zip: read %" PRId64 " failed: %s", static_cast<int64_t>(read_amount),
           strerror(errno));
     return kIoError;
@@ -481,8 +479,7 @@
 static int32_t UpdateEntryFromDataDescriptor(int fd,
                                              ZipEntry *entry) {
   uint8_t ddBuf[sizeof(DataDescriptor) + sizeof(DataDescriptor::kOptSignature)];
-  ssize_t actual = TEMP_FAILURE_RETRY(read(fd, ddBuf, sizeof(ddBuf)));
-  if (actual != sizeof(ddBuf)) {
+  if (!android::base::ReadFully(fd, ddBuf, sizeof(ddBuf))) {
     return kIoError;
   }
 
@@ -498,26 +495,14 @@
 }
 
 // Attempts to read |len| bytes into |buf| at offset |off|.
-//
-// This method uses pread64 on platforms that support it and
-// lseek64 + read on platforms that don't. This implies that
-// callers should not rely on the |fd| offset being incremented
+// Callers should not rely on the |fd| offset being incremented
 // as a side effect of this call.
-static inline ssize_t ReadAtOffset(int fd, uint8_t* buf, size_t len,
-                                   off64_t off) {
-#if !defined(_WIN32)
-  return TEMP_FAILURE_RETRY(pread64(fd, buf, len, off));
-#else
-  // The only supported platform that doesn't support pread at the moment
-  // is Windows. Only recent versions of windows support unix like forks,
-  // and even there the semantics are quite different.
+static inline bool ReadAtOffset(int fd, uint8_t* buf, size_t len, off64_t off) {
   if (lseek64(fd, off, SEEK_SET) != off) {
     ALOGW("Zip: failed seek to offset %" PRId64, off);
-    return kIoError;
+    return false;
   }
-
-  return TEMP_FAILURE_RETRY(read(fd, buf, len));
-#endif
+  return android::base::ReadFully(fd, buf, len);
 }
 
 static int32_t FindEntry(const ZipArchive* archive, const int ent,
@@ -567,9 +552,7 @@
   }
 
   uint8_t lfh_buf[sizeof(LocalFileHeader)];
-  ssize_t actual = ReadAtOffset(archive->fd, lfh_buf, sizeof(lfh_buf),
-                                 local_header_offset);
-  if (actual != sizeof(lfh_buf)) {
+  if (!ReadAtOffset(archive->fd, lfh_buf, sizeof(lfh_buf), local_header_offset)) {
     ALOGW("Zip: failed reading lfh name from offset %" PRId64,
         static_cast<int64_t>(local_header_offset));
     return kIoError;
@@ -610,10 +593,7 @@
     }
 
     uint8_t* name_buf = reinterpret_cast<uint8_t*>(malloc(nameLen));
-    ssize_t actual = ReadAtOffset(archive->fd, name_buf, nameLen,
-                                  name_offset);
-
-    if (actual != nameLen) {
+    if (!ReadAtOffset(archive->fd, name_buf, nameLen, name_offset)) {
       ALOGW("Zip: failed reading lfh name from offset %" PRId64, static_cast<int64_t>(name_offset));
       free(name_buf);
       return kIoError;
@@ -942,10 +922,9 @@
   do {
     /* read as much as we can */
     if (zstream.avail_in == 0) {
-      const ZD_TYPE getSize = (compressed_length > kBufSize) ? kBufSize : compressed_length;
-      const ZD_TYPE actual = TEMP_FAILURE_RETRY(read(fd, &read_buf[0], getSize));
-      if (actual != getSize) {
-        ALOGW("Zip: inflate read failed (" ZD " vs " ZD ")", actual, getSize);
+      const size_t getSize = (compressed_length > kBufSize) ? kBufSize : compressed_length;
+      if (!android::base::ReadFully(fd, read_buf.data(), getSize)) {
+        ALOGW("Zip: inflate read failed, getSize = %zu: %s", getSize, strerror(errno));
         return kIoError;
       }
 
@@ -1005,11 +984,9 @@
 
     // Safe conversion because kBufSize is narrow enough for a 32 bit signed
     // value.
-    const ssize_t block_size = (remaining > kBufSize) ? kBufSize : remaining;
-    const ssize_t actual = TEMP_FAILURE_RETRY(read(fd, &buf[0], block_size));
-
-    if (actual != block_size) {
-      ALOGW("CopyFileToFile: copy read failed (" ZD " vs " ZD ")", actual, block_size);
+    const size_t block_size = (remaining > kBufSize) ? kBufSize : remaining;
+    if (!android::base::ReadFully(fd, buf.data(), block_size)) {
+      ALOGW("CopyFileToFile: copy read failed, block_size = %zu: %s", block_size, strerror(errno));
       return kIoError;
     }
 
diff --git a/libziparchive/zip_archive_test.cc b/libziparchive/zip_archive_test.cc
index d426dc4..6aee1bb 100644
--- a/libziparchive/zip_archive_test.cc
+++ b/libziparchive/zip_archive_test.cc
@@ -21,9 +21,11 @@
 #include <string.h>
 #include <unistd.h>
 
+#include <memory>
 #include <vector>
 
 #include <android-base/file.h>
+#include <android-base/test_utils.h>
 #include <gtest/gtest.h>
 #include <ziparchive/zip_archive.h>
 #include <ziparchive/zip_archive_stream_entry.h>
@@ -91,7 +93,7 @@
 }
 
 TEST(ziparchive, OpenAssumeFdOwnership) {
-  int fd = open((test_data_dir + "/" + kValidZip).c_str(), O_RDONLY);
+  int fd = open((test_data_dir + "/" + kValidZip).c_str(), O_RDONLY | O_BINARY);
   ASSERT_NE(-1, fd);
   ZipArchiveHandle handle;
   ASSERT_EQ(0, OpenArchiveFd(fd, "OpenWithAssumeFdOwnership", &handle));
@@ -101,7 +103,7 @@
 }
 
 TEST(ziparchive, OpenDoNotAssumeFdOwnership) {
-  int fd = open((test_data_dir + "/" + kValidZip).c_str(), O_RDONLY);
+  int fd = open((test_data_dir + "/" + kValidZip).c_str(), O_RDONLY | O_BINARY);
   ASSERT_NE(-1, fd);
   ZipArchiveHandle handle;
   ASSERT_EQ(0, OpenArchiveFd(fd, "OpenWithAssumeFdOwnership", &handle, false));
@@ -373,30 +375,13 @@
 static const std::string kAbTxtName("ab.txt");
 static const size_t kAbUncompressedSize = 270216;
 
-static int make_temporary_file(const char* file_name_pattern) {
-  char full_path[1024];
-  // Account for differences between the host and the target.
-  //
-  // TODO: Maybe reuse bionic/tests/TemporaryFile.h.
-  snprintf(full_path, sizeof(full_path), "/data/local/tmp/%s", file_name_pattern);
-  int fd = mkstemp(full_path);
-  if (fd == -1) {
-    snprintf(full_path, sizeof(full_path), "/tmp/%s", file_name_pattern);
-    fd = mkstemp(full_path);
-  }
-
-  return fd;
-}
-
 TEST(ziparchive, EmptyEntries) {
-  char temp_file_pattern[] = "empty_entries_test_XXXXXX";
-  int fd = make_temporary_file(temp_file_pattern);
-  ASSERT_NE(-1, fd);
-  const ssize_t file_size = sizeof(kEmptyEntriesZip);
-  ASSERT_EQ(file_size, TEMP_FAILURE_RETRY(write(fd, kEmptyEntriesZip, file_size)));
+  TemporaryFile tmp_file;
+  ASSERT_NE(-1, tmp_file.fd);
+  ASSERT_TRUE(android::base::WriteFully(tmp_file.fd, kEmptyEntriesZip, sizeof(kEmptyEntriesZip)));
 
   ZipArchiveHandle handle;
-  ASSERT_EQ(0, OpenArchiveFd(fd, "EmptyEntriesTest", &handle));
+  ASSERT_EQ(0, OpenArchiveFd(tmp_file.fd, "EmptyEntriesTest", &handle));
 
   ZipEntry entry;
   ZipString empty_name;
@@ -406,27 +391,23 @@
   uint8_t buffer[1];
   ASSERT_EQ(0, ExtractToMemory(handle, &entry, buffer, 1));
 
-  char output_file_pattern[] = "empty_entries_output_XXXXXX";
-  int output_fd = make_temporary_file(output_file_pattern);
-  ASSERT_NE(-1, output_fd);
-  ASSERT_EQ(0, ExtractEntryToFile(handle, &entry, output_fd));
+
+  TemporaryFile tmp_output_file;
+  ASSERT_NE(-1, tmp_output_file.fd);
+  ASSERT_EQ(0, ExtractEntryToFile(handle, &entry, tmp_output_file.fd));
 
   struct stat stat_buf;
-  ASSERT_EQ(0, fstat(output_fd, &stat_buf));
+  ASSERT_EQ(0, fstat(tmp_output_file.fd, &stat_buf));
   ASSERT_EQ(0, stat_buf.st_size);
-
-  close(fd);
-  close(output_fd);
 }
 
 TEST(ziparchive, EntryLargerThan32K) {
-  char temp_file_pattern[] = "entry_larger_than_32k_test_XXXXXX";
-  int fd = make_temporary_file(temp_file_pattern);
-  ASSERT_NE(-1, fd);
-  ASSERT_TRUE(android::base::WriteFully(fd, reinterpret_cast<const uint8_t*>(kAbZip),
+  TemporaryFile tmp_file;
+  ASSERT_NE(-1, tmp_file.fd);
+  ASSERT_TRUE(android::base::WriteFully(tmp_file.fd, reinterpret_cast<const uint8_t*>(kAbZip),
                          sizeof(kAbZip) - 1));
   ZipArchiveHandle handle;
-  ASSERT_EQ(0, OpenArchiveFd(fd, "EntryLargerThan32KTest", &handle));
+  ASSERT_EQ(0, OpenArchiveFd(tmp_file.fd, "EntryLargerThan32KTest", &handle));
 
   ZipEntry entry;
   ZipString ab_name;
@@ -439,21 +420,21 @@
   ASSERT_EQ(0, ExtractToMemory(handle, &entry, &buffer[0], buffer.size()));
 
   // Extract the entry to a file.
-  char output_file_pattern[] = "entry_larger_than_32k_test_output_XXXXXX";
-  int output_fd = make_temporary_file(output_file_pattern);
-  ASSERT_NE(-1, output_fd);
-  ASSERT_EQ(0, ExtractEntryToFile(handle, &entry, output_fd));
+  TemporaryFile tmp_output_file;
+  ASSERT_NE(-1, tmp_output_file.fd);
+  ASSERT_EQ(0, ExtractEntryToFile(handle, &entry, tmp_output_file.fd));
 
   // Make sure the extracted file size is as expected.
   struct stat stat_buf;
-  ASSERT_EQ(0, fstat(output_fd, &stat_buf));
+  ASSERT_EQ(0, fstat(tmp_output_file.fd, &stat_buf));
   ASSERT_EQ(kAbUncompressedSize, static_cast<size_t>(stat_buf.st_size));
 
   // Read the file back to a buffer and make sure the contents are
   // the same as the memory buffer we extracted directly to.
   std::vector<uint8_t> file_contents(kAbUncompressedSize);
-  ASSERT_EQ(0, lseek64(output_fd, 0, SEEK_SET));
-  ASSERT_TRUE(android::base::ReadFully(output_fd, &file_contents[0], file_contents.size()));
+  ASSERT_EQ(0, lseek64(tmp_output_file.fd, 0, SEEK_SET));
+  ASSERT_TRUE(android::base::ReadFully(tmp_output_file.fd, &file_contents[0],
+                                       file_contents.size()));
   ASSERT_EQ(file_contents, buffer);
 
   for (int i = 0; i < 90072; ++i) {
@@ -462,35 +443,28 @@
     ASSERT_EQ('b', line[1]);
     ASSERT_EQ('\n', line[2]);
   }
-
-  close(fd);
-  close(output_fd);
 }
 
 TEST(ziparchive, TrailerAfterEOCD) {
-  char temp_file_pattern[] = "trailer_after_eocd_test_XXXXXX";
-  int fd = make_temporary_file(temp_file_pattern);
-  ASSERT_NE(-1, fd);
+  TemporaryFile tmp_file;
+  ASSERT_NE(-1, tmp_file.fd);
 
   // Create a file with 8 bytes of random garbage.
   static const uint8_t trailer[] = { 'A' ,'n', 'd', 'r', 'o', 'i', 'd', 'z' };
-  const ssize_t file_size = sizeof(kEmptyEntriesZip);
-  const ssize_t trailer_size = sizeof(trailer);
-  ASSERT_EQ(file_size, TEMP_FAILURE_RETRY(write(fd, kEmptyEntriesZip, file_size)));
-  ASSERT_EQ(trailer_size, TEMP_FAILURE_RETRY(write(fd, trailer, trailer_size)));
+  ASSERT_TRUE(android::base::WriteFully(tmp_file.fd, kEmptyEntriesZip, sizeof(kEmptyEntriesZip)));
+  ASSERT_TRUE(android::base::WriteFully(tmp_file.fd, trailer, sizeof(trailer)));
 
   ZipArchiveHandle handle;
-  ASSERT_GT(0, OpenArchiveFd(fd, "EmptyEntriesTest", &handle));
+  ASSERT_GT(0, OpenArchiveFd(tmp_file.fd, "EmptyEntriesTest", &handle));
 }
 
 TEST(ziparchive, ExtractToFile) {
-  char kTempFilePattern[] = "zip_archive_input_XXXXXX";
-  int fd = make_temporary_file(kTempFilePattern);
-  ASSERT_NE(-1, fd);
+  TemporaryFile tmp_file;
+  ASSERT_NE(-1, tmp_file.fd);
   const uint8_t data[8] = { '1', '2', '3', '4', '5', '6', '7', '8' };
-  const ssize_t data_size = sizeof(data);
+  const size_t data_size = sizeof(data);
 
-  ASSERT_EQ(data_size, TEMP_FAILURE_RETRY(write(fd, data, data_size)));
+  ASSERT_TRUE(android::base::WriteFully(tmp_file.fd, data, data_size));
 
   ZipArchiveHandle handle;
   ASSERT_EQ(0, OpenArchiveWrapper(kValidZip, &handle));
@@ -499,28 +473,25 @@
   ZipString name;
   SetZipString(&name, kATxtName);
   ASSERT_EQ(0, FindEntry(handle, name, &entry));
-  ASSERT_EQ(0, ExtractEntryToFile(handle, &entry, fd));
+  ASSERT_EQ(0, ExtractEntryToFile(handle, &entry, tmp_file.fd));
 
 
   // Assert that the first 8 bytes of the file haven't been clobbered.
   uint8_t read_buffer[data_size];
-  ASSERT_EQ(0, lseek64(fd, 0, SEEK_SET));
-  ASSERT_EQ(data_size, TEMP_FAILURE_RETRY(read(fd, read_buffer, data_size)));
+  ASSERT_EQ(0, lseek64(tmp_file.fd, 0, SEEK_SET));
+  ASSERT_TRUE(android::base::ReadFully(tmp_file.fd, read_buffer, data_size));
   ASSERT_EQ(0, memcmp(read_buffer, data, data_size));
 
   // Assert that the remainder of the file contains the incompressed data.
   std::vector<uint8_t> uncompressed_data(entry.uncompressed_length);
-  ASSERT_EQ(static_cast<ssize_t>(entry.uncompressed_length),
-            TEMP_FAILURE_RETRY(
-                read(fd, &uncompressed_data[0], entry.uncompressed_length)));
+  ASSERT_TRUE(android::base::ReadFully(tmp_file.fd, uncompressed_data.data(),
+                                       entry.uncompressed_length));
   ASSERT_EQ(0, memcmp(&uncompressed_data[0], kATxtContents.data(),
                       kATxtContents.size()));
 
   // Assert that the total length of the file is sane
-  ASSERT_EQ(data_size + static_cast<ssize_t>(kATxtContents.size()),
-            lseek64(fd, 0, SEEK_END));
-
-  close(fd);
+  ASSERT_EQ(static_cast<ssize_t>(data_size + kATxtContents.size()),
+            lseek64(tmp_file.fd, 0, SEEK_END));
 }
 
 static void ZipArchiveStreamTest(
diff --git a/libziparchive/zip_writer_test.cc b/libziparchive/zip_writer_test.cc
index fe0846d..16a574d 100644
--- a/libziparchive/zip_writer_test.cc
+++ b/libziparchive/zip_writer_test.cc
@@ -154,12 +154,22 @@
   tm->tm_mday = (zip_time >> 16) & 0x1f;
 }
 
+static struct tm MakeTm() {
+  struct tm tm;
+  memset(&tm, 0, sizeof(struct tm));
+  tm.tm_year = 2001 - 1900;
+  tm.tm_mon = 1;
+  tm.tm_mday = 12;
+  tm.tm_hour = 18;
+  tm.tm_min = 30;
+  tm.tm_sec = 20;
+  return tm;
+}
+
 TEST_F(zipwriter, WriteUncompressedZipFileWithAlignedFlagAndTime) {
   ZipWriter writer(file_);
 
-  struct tm tm;
-  memset(&tm, 0, sizeof(struct tm));
-  ASSERT_TRUE(strptime("18:30:20 1/12/2001", "%H:%M:%S %d/%m/%Y", &tm) != nullptr);
+  struct tm tm = MakeTm();
   time_t time = mktime(&tm);
   ASSERT_EQ(0, writer.StartEntryWithTime("align.txt", ZipWriter::kAlign32, time));
   ASSERT_EQ(0, writer.WriteBytes("he", 2));
@@ -210,9 +220,7 @@
 TEST_F(zipwriter, WriteUncompressedZipFileWithAlignedValueAndTime) {
   ZipWriter writer(file_);
 
-  struct tm tm;
-  memset(&tm, 0, sizeof(struct tm));
-  ASSERT_TRUE(strptime("18:30:20 1/12/2001", "%H:%M:%S %d/%m/%Y", &tm) != nullptr);
+  struct tm tm = MakeTm();
   time_t time = mktime(&tm);
   ASSERT_EQ(0, writer.StartAlignedEntryWithTime("align.txt", 0, time, 4096));
   ASSERT_EQ(0, writer.WriteBytes("he", 2));
diff --git a/rootdir/Android.mk b/rootdir/Android.mk
index 895a25d..d90f988 100644
--- a/rootdir/Android.mk
+++ b/rootdir/Android.mk
@@ -12,6 +12,18 @@
 include $(BUILD_PREBUILT)
 
 #######################################
+# init-debug.rc
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := init-debug.rc
+LOCAL_SRC_FILES := $(LOCAL_MODULE)
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_TAGS := debug
+LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/init
+
+include $(BUILD_PREBUILT)
+
+#######################################
 # asan.options
 ifneq ($(filter address,$(SANITIZE_TARGET)),)
 include $(CLEAR_VARS)
diff --git a/rootdir/init-debug.rc b/rootdir/init-debug.rc
new file mode 100644
index 0000000..435d4cb
--- /dev/null
+++ b/rootdir/init-debug.rc
@@ -0,0 +1,8 @@
+on property:persist.mmc.max_read_speed=*
+    write /sys/block/mmcblk0/max_read_speed ${persist.mmc.max_read_speed}
+
+on property:persist.mmc.max_write_speed=*
+    write /sys/block/mmcblk0/max_write_speed ${persist.mmc.max_write_speed}
+
+on property:persist.mmc.cache_size=*
+    write /sys/block/mmcblk0/cache_size ${persist.mmc.cache_size}