Merge "fs_mgr: Use slot_suffix field from bootloader_message."
diff --git a/adb/Android.mk b/adb/Android.mk
index bbdc2ea..7789035 100644
--- a/adb/Android.mk
+++ b/adb/Android.mk
@@ -248,6 +248,7 @@
     framebuffer_service.cpp \
     remount_service.cpp \
     set_verity_enable_state_service.cpp \
+    shell_service.cpp \
 
 LOCAL_CFLAGS := \
     $(ADB_COMMON_CFLAGS) \
@@ -264,8 +265,6 @@
 
 LOCAL_MODULE := adbd
 
-LOCAL_INIT_RC := adbd.rc
-
 LOCAL_FORCE_STATIC_EXECUTABLE := true
 LOCAL_MODULE_PATH := $(TARGET_ROOT_OUT_SBIN)
 LOCAL_UNSTRIPPED_PATH := $(TARGET_ROOT_OUT_SBIN_UNSTRIPPED)
diff --git a/adb/adb.cpp b/adb/adb.cpp
index eb01da8..0bd95a3 100644
--- a/adb/adb.cpp
+++ b/adb/adb.cpp
@@ -53,8 +53,6 @@
 #include <sys/mount.h>
 #endif
 
-ADB_MUTEX_DEFINE(D_lock);
-
 #if !ADB_HOST
 const char* adb_device_banner = "device";
 static android::base::LogdLogger gLogdLogger;
@@ -178,13 +176,14 @@
         {"transport", TRACE_TRANSPORT},
         {"jdwp", TRACE_JDWP},
         {"services", TRACE_SERVICES},
-        {"auth", TRACE_AUTH}};
+        {"auth", TRACE_AUTH},
+        {"shell", TRACE_SHELL}};
 
     std::vector<std::string> elements = android::base::Split(trace_setting, " ");
     for (const auto& elem : elements) {
         const auto& flag = trace_flags.find(elem);
         if (flag == trace_flags.end()) {
-            D("Unknown trace flag: %s\n", flag->first.c_str());
+            D("Unknown trace flag: %s", flag->first.c_str());
             continue;
         }
 
@@ -234,13 +233,13 @@
 
 void handle_online(atransport *t)
 {
-    D("adb: online\n");
+    D("adb: online");
     t->online = 1;
 }
 
 void handle_offline(atransport *t)
 {
-    D("adb: offline\n");
+    D("adb: offline");
     //Close the associated usb
     t->online = 0;
 
@@ -294,7 +293,7 @@
 
 static void send_ready(unsigned local, unsigned remote, atransport *t)
 {
-    D("Calling send_ready \n");
+    D("Calling send_ready");
     apacket *p = get_apacket();
     p->msg.command = A_OKAY;
     p->msg.arg0 = local;
@@ -304,7 +303,7 @@
 
 static void send_close(unsigned local, unsigned remote, atransport *t)
 {
-    D("Calling send_close \n");
+    D("Calling send_close");
     apacket *p = get_apacket();
     p->msg.command = A_CLSE;
     p->msg.arg0 = local;
@@ -339,7 +338,7 @@
 }
 
 void send_connect(atransport* t) {
-    D("Calling send_connect \n");
+    D("Calling send_connect");
     apacket* cp = get_apacket();
     cp->msg.command = A_CNXN;
     cp->msg.arg0 = t->get_protocol_version();
@@ -369,7 +368,7 @@
 }
 
 void parse_banner(const std::string& banner, atransport* t) {
-    D("parse_banner: %s\n", banner.c_str());
+    D("parse_banner: %s", banner.c_str());
 
     // The format is something like:
     // "device::ro.product.name=x;ro.product.model=y;ro.product.device=z;".
@@ -402,23 +401,23 @@
 
     const std::string& type = pieces[0];
     if (type == "bootloader") {
-        D("setting connection_state to kCsBootloader\n");
+        D("setting connection_state to kCsBootloader");
         t->connection_state = kCsBootloader;
         update_transports();
     } else if (type == "device") {
-        D("setting connection_state to kCsDevice\n");
+        D("setting connection_state to kCsDevice");
         t->connection_state = kCsDevice;
         update_transports();
     } else if (type == "recovery") {
-        D("setting connection_state to kCsRecovery\n");
+        D("setting connection_state to kCsRecovery");
         t->connection_state = kCsRecovery;
         update_transports();
     } else if (type == "sideload") {
-        D("setting connection_state to kCsSideload\n");
+        D("setting connection_state to kCsSideload");
         t->connection_state = kCsSideload;
         update_transports();
     } else {
-        D("setting connection_state to kCsHost\n");
+        D("setting connection_state to kCsHost");
         t->connection_state = kCsHost;
     }
 }
@@ -450,7 +449,7 @@
 {
     asocket *s;
 
-    D("handle_packet() %c%c%c%c\n", ((char*) (&(p->msg.command)))[0],
+    D("handle_packet() %c%c%c%c", ((char*) (&(p->msg.command)))[0],
             ((char*) (&(p->msg.command)))[1],
             ((char*) (&(p->msg.command)))[2],
             ((char*) (&(p->msg.command)))[3]);
@@ -526,7 +525,7 @@
                     /* Other READY messages must use the same local-id */
                     s->ready(s);
                 } else {
-                    D("Invalid A_OKAY(%d,%d), expected A_OKAY(%d,%d) on transport %s\n",
+                    D("Invalid A_OKAY(%d,%d), expected A_OKAY(%d,%d) on transport %s",
                       p->msg.arg0, p->msg.arg1, s->peer->id, p->msg.arg1, t->serial);
                 }
             }
@@ -547,7 +546,7 @@
                  * socket has a peer on the same transport.
                  */
                 if (p->msg.arg0 == 0 && s->peer && s->peer->transport != t) {
-                    D("Invalid A_CLSE(0, %u) from transport %s, expected transport %s\n",
+                    D("Invalid A_CLSE(0, %u) from transport %s, expected transport %s",
                       p->msg.arg1, t->serial, s->peer->transport->serial);
                 } else {
                     s->close(s);
@@ -563,7 +562,7 @@
                 p->len = p->msg.data_length;
 
                 if(s->enqueue(s, p) == 0) {
-                    D("Enqueue the socket\n");
+                    D("Enqueue the socket");
                     send_ready(s->id, rid, t);
                 }
                 return;
@@ -1125,18 +1124,36 @@
     if (!strncmp(service, "devices", 7)) {
         bool long_listing = (strcmp(service+7, "-l") == 0);
         if (long_listing || service[7] == 0) {
-            D("Getting device list...\n");
+            D("Getting device list...");
             std::string device_list = list_transports(long_listing);
-            D("Sending device list...\n");
+            D("Sending device list...");
             return SendOkay(reply_fd, device_list);
         }
         return 1;
     }
 
     if (!strcmp(service, "features")) {
-        SendOkay(reply_fd);
-        SendProtocolString(
-            reply_fd, android::base::Join(supported_features(), '\n'));
+        std::string error_msg;
+        atransport* t = acquire_one_transport(kCsAny, type, serial, &error_msg);
+        if (t != nullptr) {
+            SendOkay(reply_fd, android::base::Join(t->features(), '\n'));
+        } else {
+            SendFail(reply_fd, error_msg);
+        }
+        return 0;
+    }
+
+    if (!strncmp(service, "check-feature:", strlen("check-feature:"))) {
+        std::string error_msg;
+        atransport* t = acquire_one_transport(kCsAny, type, serial, &error_msg);
+        if (t && t->CanUseFeature(service + strlen("check-feature:"))) {
+            // We could potentially extend this to reply with the feature
+            // version if that becomes necessary.
+            SendOkay(reply_fd, "1");
+        } else {
+            // Empty response means unsupported feature.
+            SendOkay(reply_fd, "");
+        }
         return 0;
     }
 
diff --git a/adb/adb_auth.cpp b/adb/adb_auth.cpp
index 8a6b156..2364f7b 100644
--- a/adb/adb_auth.cpp
+++ b/adb/adb_auth.cpp
@@ -32,13 +32,13 @@
 
 void send_auth_request(atransport *t)
 {
-    D("Calling send_auth_request\n");
+    D("Calling send_auth_request");
     apacket *p;
     int ret;
 
     ret = adb_auth_generate_token(t->token, sizeof(t->token));
     if (ret != sizeof(t->token)) {
-        D("Error generating token ret=%d\n", ret);
+        D("Error generating token ret=%d", ret);
         return;
     }
 
@@ -52,13 +52,13 @@
 
 void send_auth_response(uint8_t *token, size_t token_size, atransport *t)
 {
-    D("Calling send_auth_response\n");
+    D("Calling send_auth_response");
     apacket *p = get_apacket();
     int ret;
 
     ret = adb_auth_sign(t->key, token, token_size, p->data);
     if (!ret) {
-        D("Error signing the token\n");
+        D("Error signing the token");
         put_apacket(p);
         return;
     }
@@ -71,13 +71,13 @@
 
 void send_auth_publickey(atransport *t)
 {
-    D("Calling send_auth_publickey\n");
+    D("Calling send_auth_publickey");
     apacket *p = get_apacket();
     int ret;
 
     ret = adb_auth_get_userkey(p->data, MAX_PAYLOAD_V1);
     if (!ret) {
-        D("Failed to get user public key\n");
+        D("Failed to get user public key");
         put_apacket(p);
         return;
     }
diff --git a/adb/adb_auth_client.cpp b/adb/adb_auth_client.cpp
index c3af024..cedc847 100644
--- a/adb/adb_auth_client.cpp
+++ b/adb/adb_auth_client.cpp
@@ -60,7 +60,7 @@
 
     f = fopen(file, "re");
     if (!f) {
-        D("Can't open '%s'\n", file);
+        D("Can't open '%s'", file);
         return;
     }
 
@@ -69,7 +69,7 @@
         auto key = reinterpret_cast<adb_public_key*>(
             calloc(1, sizeof(adb_public_key) + 4));
         if (key == nullptr) {
-            D("Can't malloc key\n");
+            D("Can't malloc key");
             break;
         }
 
@@ -79,13 +79,13 @@
 
         ret = __b64_pton(buf, (u_char *)&key->key, sizeof(key->key) + 4);
         if (ret != sizeof(key->key)) {
-            D("%s: Invalid base64 data ret=%d\n", file, ret);
+            D("%s: Invalid base64 data ret=%d", file, ret);
             free(key);
             continue;
         }
 
         if (key->key.len != RSANUMWORDS) {
-            D("%s: Invalid key len %d\n", file, key->key.len);
+            D("%s: Invalid key len %d", file, key->key.len);
             free(key);
             continue;
         }
@@ -117,7 +117,7 @@
 
     while ((path = *paths++)) {
         if (!stat(path, &buf)) {
-            D("Loading keys from '%s'\n", path);
+            D("Loading keys from '%s'", path);
             read_keys(path, list);
         }
     }
@@ -163,7 +163,7 @@
 
 static void usb_disconnected(void* unused, atransport* t)
 {
-    D("USB disconnect\n");
+    D("USB disconnect");
     usb_transport = NULL;
     needs_retry = false;
 }
@@ -176,7 +176,7 @@
     if (events & FDE_READ) {
         ret = unix_read(fd, response, sizeof(response));
         if (ret <= 0) {
-            D("Framework disconnect\n");
+            D("Framework disconnect");
             if (usb_transport)
                 fdevent_remove(&usb_transport->auth_fde);
             framework_fd = -1;
@@ -199,26 +199,26 @@
     }
 
     if (framework_fd < 0) {
-        D("Client not connected\n");
+        D("Client not connected");
         needs_retry = true;
         return;
     }
 
     if (key[len - 1] != '\0') {
-        D("Key must be a null-terminated string\n");
+        D("Key must be a null-terminated string");
         return;
     }
 
     ret = snprintf(msg, sizeof(msg), "PK%s", key);
     if (ret >= (signed)sizeof(msg)) {
-        D("Key too long. ret=%d\n", ret);
+        D("Key too long. ret=%d", ret);
         return;
     }
-    D("Sending '%s'\n", msg);
+    D("Sending '%s'", msg);
 
     ret = unix_write(framework_fd, msg, ret);
     if (ret < 0) {
-        D("Failed to write PK, errno=%d\n", errno);
+        D("Failed to write PK, errno=%d", errno);
         return;
     }
 
@@ -236,7 +236,7 @@
 
     s = adb_socket_accept(fd, &addr, &alen);
     if (s < 0) {
-        D("Failed to accept: errno=%d\n", errno);
+        D("Failed to accept: errno=%d", errno);
         return;
     }
 
@@ -251,7 +251,7 @@
 void adbd_cloexec_auth_socket() {
     int fd = android_get_control_socket("adbd");
     if (fd == -1) {
-        D("Failed to get adbd socket\n");
+        D("Failed to get adbd socket");
         return;
     }
     fcntl(fd, F_SETFD, FD_CLOEXEC);
@@ -260,12 +260,12 @@
 void adbd_auth_init(void) {
     int fd = android_get_control_socket("adbd");
     if (fd == -1) {
-        D("Failed to get adbd socket\n");
+        D("Failed to get adbd socket");
         return;
     }
 
     if (listen(fd, 4) == -1) {
-        D("Failed to listen on '%d'\n", fd);
+        D("Failed to listen on '%d'", fd);
         return;
     }
 
diff --git a/adb/adb_auth_host.cpp b/adb/adb_auth_host.cpp
index e7f82a9..749fec2 100644
--- a/adb/adb_auth_host.cpp
+++ b/adb/adb_auth_host.cpp
@@ -164,26 +164,26 @@
 
     if (snprintf(path, sizeof(path), "%s.pub", private_key_path) >=
         (int)sizeof(path)) {
-        D("Path too long while writing public key\n");
+        D("Path too long while writing public key");
         return 0;
     }
 
     if (!RSA_to_RSAPublicKey(private_key, &pkey)) {
-        D("Failed to convert to publickey\n");
+        D("Failed to convert to publickey");
         return 0;
     }
 
     outfile = fopen(path, "w");
     if (!outfile) {
-        D("Failed to open '%s'\n", path);
+        D("Failed to open '%s'", path);
         return 0;
     }
 
-    D("Writing public key to '%s'\n", path);
+    D("Writing public key to '%s'", path);
 
 #if defined(OPENSSL_IS_BORINGSSL)
     if (!EVP_EncodedLength(&encoded_length, sizeof(pkey))) {
-        D("Public key too large to base64 encode\n");
+        D("Public key too large to base64 encode");
         goto out;
     }
 #else
@@ -194,7 +194,7 @@
 
     encoded = new uint8_t[encoded_length];
     if (encoded == nullptr) {
-        D("Allocation failure\n");
+        D("Allocation failure");
         goto out;
     }
 
@@ -203,7 +203,7 @@
 
     if (fwrite(encoded, encoded_length, 1, outfile) != 1 ||
         fwrite(info, strlen(info), 1, outfile) != 1) {
-        D("Write error while writing public key\n");
+        D("Write error while writing public key");
         goto out;
     }
 
@@ -226,10 +226,10 @@
     FILE *f = NULL;
     int ret = 0;
 
-    D("generate_key '%s'\n", file);
+    D("generate_key '%s'", file);
 
     if (!pkey || !exponent || !rsa) {
-        D("Failed to allocate key\n");
+        D("Failed to allocate key");
         goto out;
     }
 
@@ -241,7 +241,7 @@
 
     f = fopen(file, "w");
     if (!f) {
-        D("Failed to open '%s'\n", file);
+        D("Failed to open '%s'", file);
         umask(old_mask);
         goto out;
     }
@@ -249,12 +249,12 @@
     umask(old_mask);
 
     if (!PEM_write_PrivateKey(f, pkey, NULL, NULL, 0, NULL, NULL)) {
-        D("Failed to write key\n");
+        D("Failed to write key");
         goto out;
     }
 
     if (!write_public_keyfile(rsa, file)) {
-        D("Failed to write public key\n");
+        D("Failed to write public key");
         goto out;
     }
 
@@ -271,11 +271,11 @@
 
 static int read_key(const char *file, struct listnode *list)
 {
-    D("read_key '%s'\n", file);
+    D("read_key '%s'", file);
 
     FILE* fp = fopen(file, "r");
     if (!fp) {
-        D("Failed to open '%s': %s\n", file, strerror(errno));
+        D("Failed to open '%s': %s", file, strerror(errno));
         return 0;
     }
 
@@ -283,7 +283,7 @@
     key->rsa = RSA_new();
 
     if (!PEM_read_RSAPrivateKey(fp, &key->rsa, NULL, NULL)) {
-        D("Failed to read key\n");
+        D("Failed to read key");
         fclose(fp);
         RSA_free(key->rsa);
         delete key;
@@ -307,7 +307,7 @@
         WCHAR path[MAX_PATH];
         const HRESULT hr = SHGetFolderPathW(NULL, CSIDL_PROFILE, NULL, 0, path);
         if (FAILED(hr)) {
-            D("SHGetFolderPathW failed: %s\n",
+            D("SHGetFolderPathW failed: %s",
               SystemErrorCodeToString(hr).c_str());
             return -1;
         }
@@ -322,7 +322,7 @@
     format = "%s/%s";
 #endif
 
-    D("home '%s'\n", home);
+    D("home '%s'", home);
 
     if (snprintf(android_dir, sizeof(android_dir), format, home,
                         ANDROID_PATH) >= (int)sizeof(android_dir))
@@ -330,7 +330,7 @@
 
     if (stat(android_dir, &buf)) {
         if (adb_mkdir(android_dir, 0750) < 0) {
-            D("Cannot mkdir '%s'\n", android_dir);
+            D("Cannot mkdir '%s'", android_dir);
             return -1;
         }
     }
@@ -346,15 +346,15 @@
 
     ret = get_user_keyfilepath(path, sizeof(path));
     if (ret < 0 || ret >= (signed)sizeof(path)) {
-        D("Error getting user key filename\n");
+        D("Error getting user key filename");
         return 0;
     }
 
-    D("user key '%s'\n", path);
+    D("user key '%s'", path);
 
     if (stat(path, &buf) == -1) {
         if (!generate_key(path)) {
-            D("Failed to generate new key\n");
+            D("Failed to generate new key");
             return 0;
         }
     }
@@ -370,7 +370,7 @@
 
     for (auto& path : android::base::Split(adb_keys_path, ENV_PATH_SEPARATOR_STR)) {
         if (!read_key(path.c_str(), key_list)) {
-            D("Failed to read '%s'\n", path.c_str());
+            D("Failed to read '%s'", path.c_str());
         }
     }
 }
@@ -382,7 +382,7 @@
     struct adb_private_key *key = node_to_item(node, struct adb_private_key, node);
 
     if (token_size != TOKEN_SIZE) {
-        D("Unexpected token size %zd\n", token_size);
+        D("Unexpected token size %zd", token_size);
         return 0;
     }
 
@@ -390,7 +390,7 @@
         return 0;
     }
 
-    D("adb_auth_sign len=%d\n", len);
+    D("adb_auth_sign len=%d", len);
     return (int)len;
 }
 
@@ -421,7 +421,7 @@
     char path[PATH_MAX];
     int ret = get_user_keyfilepath(path, sizeof(path) - 4);
     if (ret < 0 || ret >= (signed)(sizeof(path) - 4)) {
-        D("Error getting user key filename\n");
+        D("Error getting user key filename");
         return 0;
     }
     strcat(path, ".pub");
@@ -433,12 +433,12 @@
     unsigned size;
     char* file_data = reinterpret_cast<char*>(load_file(path, &size));
     if (file_data == nullptr) {
-        D("Can't load '%s'\n", path);
+        D("Can't load '%s'", path);
         return 0;
     }
 
     if (len < (size_t)(size + 1)) {
-        D("%s: Content too large ret=%d\n", path, size);
+        D("%s: Content too large ret=%d", path, size);
         free(file_data);
         return 0;
     }
@@ -460,13 +460,13 @@
 {
     int ret;
 
-    D("adb_auth_init\n");
+    D("adb_auth_init");
 
     list_init(&key_list);
 
     ret = get_user_key(&key_list);
     if (!ret) {
-        D("Failed to get user key\n");
+        D("Failed to get user key");
         return;
     }
 
diff --git a/adb/adb_client.cpp b/adb/adb_client.cpp
index a1bbb78..ff68415 100644
--- a/adb/adb_client.cpp
+++ b/adb/adb_client.cpp
@@ -90,14 +90,14 @@
         adb_close(fd);
         return -1;
     }
-    D("Switch transport in progress\n");
+    D("Switch transport in progress");
 
     if (!adb_status(fd, error)) {
         adb_close(fd);
-        D("Switch transport failed: %s\n", error->c_str());
+        D("Switch transport failed: %s", error->c_str());
         return -1;
     }
-    D("Switch transport success\n");
+    D("Switch transport success");
     return 0;
 }
 
@@ -123,7 +123,7 @@
 }
 
 int _adb_connect(const std::string& service, std::string* error) {
-    D("_adb_connect: %s\n", service.c_str());
+    D("_adb_connect: %s", service.c_str());
     if (service.empty() || service.size() > 1024) {
         *error = android::base::StringPrintf("bad service name length (%zd)",
                                              service.size());
@@ -164,7 +164,7 @@
         return -1;
     }
 
-    D("_adb_connect: return fd %d\n", fd);
+    D("_adb_connect: return fd %d", fd);
     return fd;
 }
 
@@ -172,7 +172,7 @@
     // first query the adb server's version
     int fd = _adb_connect("host:version", error);
 
-    D("adb_connect: service %s\n", service.c_str());
+    D("adb_connect: service %s", service.c_str());
     if (fd == -2 && __adb_server_name) {
         fprintf(stderr,"** Cannot start server on remote host\n");
         // error is the original network connection error
@@ -246,11 +246,11 @@
 
     fd = _adb_connect(service, error);
     if (fd == -1) {
-        D("_adb_connect error: %s\n", error->c_str());
+        D("_adb_connect error: %s", error->c_str());
     } else if(fd == -2) {
         fprintf(stderr,"** daemon still not running\n");
     }
-    D("adb_connect: return fd %d\n", fd);
+    D("adb_connect: return fd %d", fd);
 
     return fd;
 error:
@@ -277,7 +277,7 @@
 }
 
 bool adb_query(const std::string& service, std::string* result, std::string* error) {
-    D("adb_query: %s\n", service.c_str());
+    D("adb_query: %s", service.c_str());
     int fd = adb_connect(service, error);
     if (fd < 0) {
         return false;
diff --git a/adb/adb_io.cpp b/adb/adb_io.cpp
index 7092609..14e295f 100644
--- a/adb/adb_io.cpp
+++ b/adb/adb_io.cpp
@@ -68,23 +68,23 @@
 
     size_t len0 = len;
 
-    D("readx: fd=%d wanted=%zu\n", fd, len);
+    D("readx: fd=%d wanted=%zu", fd, len);
     while (len > 0) {
         int r = adb_read(fd, p, len);
         if (r > 0) {
             len -= r;
             p += r;
         } else if (r == -1) {
-            D("readx: fd=%d error %d: %s\n", fd, errno, strerror(errno));
+            D("readx: fd=%d error %d: %s", fd, errno, strerror(errno));
             return false;
         } else {
-            D("readx: fd=%d disconnected\n", fd);
+            D("readx: fd=%d disconnected", fd);
             errno = 0;
             return false;
         }
     }
 
-    D("readx: fd=%d wanted=%zu got=%zu\n", fd, len0, len0 - len);
+    D("readx: fd=%d wanted=%zu got=%zu", fd, len0, len0 - len);
     if (ADB_TRACING) {
         dump_hex(reinterpret_cast<const unsigned char*>(buf), len0);
     }
@@ -104,12 +104,12 @@
     while (len > 0) {
         r = adb_write(fd, p, len);
         if (r == -1) {
-            D("writex: fd=%d error %d: %s\n", fd, errno, strerror(errno));
+            D("writex: fd=%d error %d: %s", fd, errno, strerror(errno));
             if (errno == EAGAIN) {
                 adb_sleep_ms(1); // just yield some cpu time
                 continue;
             } else if (errno == EPIPE) {
-                D("writex: fd=%d disconnected\n", fd);
+                D("writex: fd=%d disconnected", fd);
                 errno = 0;
                 return false;
             } else {
diff --git a/adb/adb_trace.h b/adb/adb_trace.h
index 4e03165..623108e 100644
--- a/adb/adb_trace.h
+++ b/adb/adb_trace.h
@@ -17,11 +17,8 @@
 #ifndef __ADB_TRACE_H
 #define __ADB_TRACE_H
 
-#if !ADB_HOST
-#include <android/log.h>
-#else
-#include <stdio.h>
-#endif
+#include <base/logging.h>
+#include <base/stringprintf.h>
 
 /* IMPORTANT: if you change the following list, don't
  * forget to update the corresponding 'tags' table in
@@ -40,54 +37,23 @@
     TRACE_SERVICES,
     TRACE_AUTH,
     TRACE_FDEVENT,
+    TRACE_SHELL
 };
 
 extern int adb_trace_mask;
 extern unsigned char adb_trace_output_count;
 void adb_trace_init(char**);
 
-#  define ADB_TRACING  ((adb_trace_mask & (1 << TRACE_TAG)) != 0)
+#define ADB_TRACING  ((adb_trace_mask & (1 << TRACE_TAG)) != 0)
 
-/* you must define TRACE_TAG before using this macro */
-#if ADB_HOST
-#  define D(fmt, ...) \
+// You must define TRACE_TAG before using this macro.
+#define D(...) \
         do { \
             if (ADB_TRACING) { \
                 int saved_errno = errno; \
-                adb_mutex_lock(&D_lock); \
-                errno = saved_errno; \
-                fprintf(stderr, "%5d:%5lu %s | " fmt, \
-                        getpid(), adb_thread_id(), __FUNCTION__, ## __VA_ARGS__); \
-                fflush(stderr); \
-                adb_mutex_unlock(&D_lock); \
+                LOG(INFO) << android::base::StringPrintf(__VA_ARGS__); \
                 errno = saved_errno; \
            } \
         } while (0)
-#  define DR(...) \
-        do { \
-            if (ADB_TRACING) { \
-                int saved_errno = errno; \
-                adb_mutex_lock(&D_lock); \
-                errno = saved_errno; \
-                fprintf(stderr, __VA_ARGS__); \
-                fflush(stderr); \
-                adb_mutex_unlock(&D_lock); \
-                errno = saved_errno; \
-           } \
-        } while (0)
-#else
-#  define D(...) \
-        do { \
-            if (ADB_TRACING) { \
-                __android_log_print(ANDROID_LOG_INFO, __FUNCTION__, __VA_ARGS__); \
-            } \
-        } while (0)
-#  define DR(...) \
-        do { \
-            if (ADB_TRACING) { \
-                __android_log_print(ANDROID_LOG_INFO, __FUNCTION__, __VA_ARGS__); \
-            } \
-        } while (0)
-#endif /* ADB_HOST */
 
 #endif /* __ADB_TRACE_H */
diff --git a/adb/adb_utils.cpp b/adb/adb_utils.cpp
index e5dc692..72ee901 100644
--- a/adb/adb_utils.cpp
+++ b/adb/adb_utils.cpp
@@ -170,7 +170,7 @@
         line.push_back(c);
     }
 
-    DR("%s\n", line.c_str());
+    D("%s", line.c_str());
 }
 
 bool parse_host_and_port(const std::string& address,
diff --git a/adb/adbd.rc b/adb/adbd.rc
deleted file mode 100644
index b91d8b5..0000000
--- a/adb/adbd.rc
+++ /dev/null
@@ -1,14 +0,0 @@
-on post-fs-data
-    mkdir /data/misc/adb 02750 system shell
-    mkdir /data/adb 0700 root root
-
-# adbd is controlled via property triggers in init.<platform>.usb.rc
-service adbd /sbin/adbd --root_seclabel=u:r:su:s0
-    class core
-    socket adbd stream 660 system system
-    disabled
-    seclabel u:r:adbd:s0
-
-# adbd on at boot in emulator
-on property:ro.kernel.qemu=1
-    start adbd
diff --git a/adb/client/main.cpp b/adb/client/main.cpp
index 8d644d9..6e27c0f 100644
--- a/adb/client/main.cpp
+++ b/adb/client/main.cpp
@@ -163,7 +163,7 @@
 #endif
     }
 
-    D("Event loop starting\n");
+    D("Event loop starting");
     fdevent_loop();
 
     return 0;
diff --git a/adb/commandline.cpp b/adb/commandline.cpp
index 6325e64..4fe0c25 100644
--- a/adb/commandline.cpp
+++ b/adb/commandline.cpp
@@ -258,10 +258,10 @@
 
 static void read_and_dump(int fd) {
     while (fd >= 0) {
-        D("read_and_dump(): pre adb_read(fd=%d)\n", fd);
+        D("read_and_dump(): pre adb_read(fd=%d)", fd);
         char buf[BUFSIZ];
         int len = adb_read(fd, buf, sizeof(buf));
-        D("read_and_dump(): post adb_read(fd=%d): len=%d\n", fd, len);
+        D("read_and_dump(): post adb_read(fd=%d): len=%d", fd, len);
         if (len <= 0) {
             break;
         }
@@ -297,7 +297,7 @@
     int old_stdout_mode = -1;
 #endif
 
-    D("copy_to_file(%d -> %d)\n", inFd, outFd);
+    D("copy_to_file(%d -> %d)", inFd, outFd);
 
     if (inFd == STDIN_FILENO) {
         stdin_raw_init(STDIN_FILENO);
@@ -325,11 +325,11 @@
             len = adb_read(inFd, buf, BUFSIZE);
         }
         if (len == 0) {
-            D("copy_to_file() : read 0 bytes; exiting\n");
+            D("copy_to_file() : read 0 bytes; exiting");
             break;
         }
         if (len < 0) {
-            D("copy_to_file(): read failed: %s\n", strerror(errno));
+            D("copy_to_file(): read failed: %s", strerror(errno));
             break;
         }
         if (outFd == STDOUT_FILENO) {
@@ -358,7 +358,7 @@
     }
 #endif
 
-    D("copy_to_file() finished after %lu bytes\n", total);
+    D("copy_to_file() finished after %lu bytes", total);
     free(buf);
 }
 
@@ -378,9 +378,9 @@
 
     while (true) {
         /* fdi is really the client's stdin, so use read, not adb_read here */
-        D("stdin_read_thread(): pre unix_read(fdi=%d,...)\n", fdi);
+        D("stdin_read_thread(): pre unix_read(fdi=%d,...)", fdi);
         r = unix_read(fdi, buf, 1024);
-        D("stdin_read_thread(): post unix_read(fdi=%d,...)\n", fdi);
+        D("stdin_read_thread(): post unix_read(fdi=%d,...)", fdi);
         if (r <= 0) break;
         for (n = 0; n < r; n++){
             switch(buf[n]) {
@@ -777,7 +777,7 @@
         cmd += " " + escape_arg(*argv++);
     }
 
-    D("backup. filename=%s cmd=%s\n", filename, cmd.c_str());
+    D("backup. filename=%s cmd=%s", filename, cmd.c_str());
     std::string error;
     int fd = adb_connect(cmd, &error);
     if (fd < 0) {
@@ -1152,7 +1152,7 @@
         }
 
         if (argc < 2) {
-            D("starting interactive shell\n");
+            D("starting interactive shell");
             r = interactive_shell();
             if (h) {
                 printf("\x1b[0m");
@@ -1171,14 +1171,14 @@
         }
 
         while (true) {
-            D("interactive shell loop. cmd=%s\n", cmd.c_str());
+            D("interactive shell loop. cmd=%s", cmd.c_str());
             std::string error;
             int fd = adb_connect(cmd, &error);
             int r;
             if (fd >= 0) {
-                D("about to read_and_dump(fd=%d)\n", fd);
+                D("about to read_and_dump(fd=%d)", fd);
                 read_and_dump(fd);
-                D("read_and_dump() done.\n");
+                D("read_and_dump() done.");
                 adb_close(fd);
                 r = 0;
             } else {
@@ -1190,7 +1190,7 @@
                 printf("\x1b[0m");
                 fflush(stdout);
             }
-            D("interactive shell loop. return r=%d\n", r);
+            D("interactive shell loop. return r=%d", r);
             return r;
         }
     }
@@ -1444,7 +1444,7 @@
         return 0;
     }
     else if (!strcmp(argv[0], "features")) {
-        return adb_query_command("host:features");
+        return adb_query_command(format_host_command("features", transport_type, serial));
     }
 
     usage();
diff --git a/adb/daemon/main.cpp b/adb/daemon/main.cpp
index 2eba625..cb0cb3d 100644
--- a/adb/daemon/main.cpp
+++ b/adb/daemon/main.cpp
@@ -162,7 +162,7 @@
             PLOG(FATAL) << "Could not setuid";
         }
 
-        D("Local port disabled\n");
+        D("Local port disabled");
     } else {
         if (root_seclabel != nullptr) {
             if (setcon(root_seclabel) < 0) {
@@ -197,7 +197,7 @@
 
     int port;
     if (sscanf(prop_port, "%d", &port) == 1 && port > 0) {
-        printf("using port=%d\n", port);
+        D("using port=%d", port);
         // Listen on TCP port specified by service.adb.tcp.port property.
         local_init(port);
     } else if (!is_usb) {
@@ -205,11 +205,11 @@
         local_init(DEFAULT_ADB_LOCAL_TRANSPORT_PORT);
     }
 
-    D("adbd_main(): pre init_jdwp()\n");
+    D("adbd_main(): pre init_jdwp()");
     init_jdwp();
-    D("adbd_main(): post init_jdwp()\n");
+    D("adbd_main(): post init_jdwp()");
 
-    D("Event loop starting\n");
+    D("Event loop starting");
     fdevent_loop();
 
     return 0;
@@ -261,6 +261,6 @@
 
     adb_trace_init(argv);
 
-    D("Handling main()\n");
+    D("Handling main()");
     return adbd_main(DEFAULT_ADB_PORT);
 }
diff --git a/adb/fdevent.cpp b/adb/fdevent.cpp
index d25bbfb..db5157f 100644
--- a/adb/fdevent.cpp
+++ b/adb/fdevent.cpp
@@ -331,11 +331,11 @@
     do {                                                                     \
         printed_out = snprintf(pb, max_chars, __VA_ARGS__);                  \
         if (printed_out <= 0) {                                              \
-            D("... snprintf failed.\n");                                     \
+            D("... snprintf failed.");                                     \
             return;                                                          \
         }                                                                    \
         if (max_chars < (unsigned int)printed_out) {                         \
-            D("... snprintf out of space.\n");                               \
+            D("... snprintf out of space.");                               \
             return;                                                          \
         }                                                                    \
         pb += printed_out;                                                   \
@@ -354,7 +354,7 @@
         }
         SAFE_SPRINTF(" ");
     }
-    D("%s fd_table[]->fd = {%s}\n", extra_msg, msg_buff);
+    D("%s fd_table[]->fd = {%s}", extra_msg, msg_buff);
 }
 #endif
 
@@ -373,7 +373,7 @@
 
     n = select(select_n, &rfd, &wfd, &efd, NULL);
     int saved_errno = errno;
-    D("select() returned n=%d, errno=%d\n", n, n<0?saved_errno:0);
+    D("select() returned n=%d, errno=%d", n, n<0?saved_errno:0);
 
     dump_all_fds("post select()");
 
@@ -387,7 +387,7 @@
             FD_ZERO(&rfd);
             break;
         default:
-            D("Unexpected select() error=%d\n", saved_errno);
+            D("Unexpected select() error=%d", saved_errno);
             return;
         }
     }
@@ -410,7 +410,7 @@
 
             fde->events |= events;
 
-            D("got events fde->fd=%d events=%04x, state=%04x\n",
+            D("got events fde->fd=%d events=%04x, state=%04x",
                 fde->fd, fde->events, fde->state);
             if(fde->state & FDE_PENDING) continue;
             fde->state |= FDE_PENDING;
@@ -516,7 +516,7 @@
                                        void* /* userdata */)
 {
 
-    D("subproc handling on fd=%d ev=%04x\n", fd, ev);
+    D("subproc handling on fd=%d ev=%04x", fd, ev);
 
     // Hook oneself back into the fde's suitable for select() on read.
     if((fd < 0) || (fd >= fd_table_max)) {
@@ -532,18 +532,18 @@
           FATAL("Failed to read the subproc's fd from fd=%d\n", fd);
       }
       if((subproc_fd < 0) || (subproc_fd >= fd_table_max)) {
-          D("subproc_fd %d out of range 0, fd_table_max=%d\n",
+          D("subproc_fd %d out of range 0, fd_table_max=%d",
             subproc_fd, fd_table_max);
           return;
       }
       fdevent *subproc_fde = fd_table[subproc_fd];
       if(!subproc_fde) {
-          D("subproc_fd %d cleared from fd_table\n", subproc_fd);
+          D("subproc_fd %d cleared from fd_table", subproc_fd);
           return;
       }
       if(subproc_fde->fd != subproc_fd) {
           // Already reallocated?
-          D("subproc_fd %d != fd_table[].fd %d\n", subproc_fd, subproc_fde->fd);
+          D("subproc_fd %d != fd_table[].fd %d", subproc_fd, subproc_fde->fd);
           return;
       }
 
@@ -551,7 +551,7 @@
 
       int rcount = 0;
       ioctl(subproc_fd, FIONREAD, &rcount);
-      D("subproc with fd=%d  has rcount=%d err=%d\n",
+      D("subproc with fd=%d  has rcount=%d err=%d",
         subproc_fd, rcount, errno);
 
       if(rcount) {
@@ -561,7 +561,7 @@
         return;
       }
 
-      D("subproc_fde.state=%04x\n", subproc_fde->state);
+      D("subproc_fde.state=%04x", subproc_fde->state);
       subproc_fde->events |= FDE_READ;
       if(subproc_fde->state & FDE_PENDING) {
         return;
@@ -578,7 +578,7 @@
     if(adb_socketpair(s)) {
         FATAL("cannot create shell-exit socket-pair\n");
     }
-    D("socketpair: (%d,%d)\n", s[0], s[1]);
+    D("socketpair: (%d,%d)", s[0], s[1]);
 
     SHELL_EXIT_NOTIFY_FD = s[0];
     fdevent *fde;
@@ -689,7 +689,7 @@
 #endif // !ADB_HOST
 
     while (true) {
-        D("--- ---- waiting for events\n");
+        D("--- ---- waiting for events");
 
         fdevent_process();
 
diff --git a/adb/file_sync_client.cpp b/adb/file_sync_client.cpp
index 94876ee..9bc634c 100644
--- a/adb/file_sync_client.cpp
+++ b/adb/file_sync_client.cpp
@@ -73,6 +73,7 @@
     size_t path_length = strlen(path);
     if (path_length > 1024) {
         fprintf(stderr, "SendRequest failed: path too long: %zu", path_length);
+        errno = ENAMETOOLONG;
         return false;
     }
 
@@ -256,28 +257,41 @@
     syncsendbuf* sbuf = &send_buffer;
 
     std::string path_and_mode = android::base::StringPrintf("%s,%d", rpath, mode);
-    if (!SendRequest(sc.fd, ID_SEND, path_and_mode.c_str())) goto fail;
+    if (!SendRequest(sc.fd, ID_SEND, path_and_mode.c_str())) {
+        fprintf(stderr, "failed to send ID_SEND message '%s': %s\n",
+                path_and_mode.c_str(), strerror(errno));
+        return false;
+    }
 
     if (S_ISREG(mode)) {
         if (!write_data_file(sc, lpath, sbuf, show_progress)) return false;
     } else if (S_ISLNK(mode)) {
         if (!write_data_link(sc, lpath, sbuf)) return false;
     } else {
-        goto fail;
+        fprintf(stderr, "local file '%s' has unsupported mode: 0o%o\n", lpath, mode);
+        return false;
     }
 
     syncmsg msg;
     msg.data.id = ID_DONE;
     msg.data.size = mtime;
-    if (!WriteFdExactly(sc.fd, &msg.data, sizeof(msg.data))) goto fail;
+    if (!WriteFdExactly(sc.fd, &msg.data, sizeof(msg.data))) {
+        fprintf(stderr, "failed to send ID_DONE message for '%s': %s\n", lpath, strerror(errno));
+        return false;
+    }
 
-    if (!ReadFdExactly(sc.fd, &msg.status, sizeof(msg.status))) goto fail;
-
+    if (!ReadFdExactly(sc.fd, &msg.status, sizeof(msg.status))) {
+        fprintf(stderr, "failed to read ID_DONE response for '%s': %s\n", lpath, strerror(errno));
+        return false;
+    }
     if (msg.status.id != ID_OKAY) {
         if (msg.status.id == ID_FAIL) {
             size_t len = msg.status.msglen;
             if (len > 256) len = 256;
-            if (!ReadFdExactly(sc.fd, sbuf->data, len)) goto fail;
+            if (!ReadFdExactly(sc.fd, sbuf->data, len)) {
+                fprintf(stderr, "failed to read failure reason (!): %s\n", strerror(errno));
+                return false;
+            }
             sbuf->data[len] = 0;
         } else {
             strcpy(sbuf->data, "unknown reason");
@@ -287,10 +301,6 @@
     }
 
     return true;
-
-fail:
-    fprintf(stderr, "protocol failure\n");
-    return false;
 }
 
 static int sync_recv(SyncConnection& sc, const char* rpath, const char* lpath, bool show_progress) {
diff --git a/adb/file_sync_service.cpp b/adb/file_sync_service.cpp
index 3793b8e..8db9ca7 100644
--- a/adb/file_sync_service.cpp
+++ b/adb/file_sync_service.cpp
@@ -130,7 +130,7 @@
 }
 
 static bool SendSyncFail(int fd, const std::string& reason) {
-    D("sync: failure: %s\n", reason.c_str());
+    D("sync: failure: %s", reason.c_str());
 
     syncmsg msg;
     msg.data.id = ID_FAIL;
@@ -346,7 +346,7 @@
 }
 
 static bool handle_sync_command(int fd, std::vector<char>& buffer) {
-    D("sync: waiting for request\n");
+    D("sync: waiting for request");
 
     SyncRequest request;
     if (!ReadFdExactly(fd, &request, sizeof(request))) {
@@ -366,7 +366,7 @@
     name[path_length] = 0;
 
     const char* id = reinterpret_cast<const char*>(&request.id);
-    D("sync: '%.4s' '%s'\n", id, name);
+    D("sync: '%.4s' '%s'", id, name);
 
     switch (request.id) {
       case ID_STAT:
@@ -398,6 +398,6 @@
     while (handle_sync_command(fd, buffer)) {
     }
 
-    D("sync: done\n");
+    D("sync: done");
     adb_close(fd);
 }
diff --git a/adb/jdwp_service.cpp b/adb/jdwp_service.cpp
index 06e7780..0fa0732 100644
--- a/adb/jdwp_service.cpp
+++ b/adb/jdwp_service.cpp
@@ -218,7 +218,7 @@
         calloc(1, sizeof(*proc)));
 
     if (proc == NULL) {
-        D("not enough memory to create new JDWP process\n");
+        D("not enough memory to create new JDWP process");
         return NULL;
     }
 
@@ -229,7 +229,7 @@
 
     proc->fde = fdevent_create( socket, jdwp_process_event, proc );
     if (proc->fde == NULL) {
-        D("could not create fdevent for new JDWP process\n" );
+        D("could not create fdevent for new JDWP process" );
         free(proc);
         return NULL;
     }
@@ -271,13 +271,13 @@
                     if (errno == EAGAIN)
                         return;
                     /* this can fail here if the JDWP process crashes very fast */
-                    D("weird unknown JDWP process failure: %s\n",
+                    D("weird unknown JDWP process failure: %s",
                       strerror(errno));
 
                     goto CloseProcess;
                 }
                 if (len == 0) {  /* end of stream ? */
-                    D("weird end-of-stream from unknown JDWP process\n");
+                    D("weird end-of-stream from unknown JDWP process");
                     goto CloseProcess;
                 }
                 p            += len;
@@ -289,12 +289,12 @@
             temp[4] = 0;
 
             if (sscanf( temp, "%04x", &proc->pid ) != 1) {
-                D("could not decode JDWP %p PID number: '%s'\n", proc, temp);
+                D("could not decode JDWP %p PID number: '%s'", proc, temp);
                 goto CloseProcess;
             }
 
             /* all is well, keep reading to detect connection closure */
-            D("Adding pid %d to jdwp process list\n", proc->pid);
+            D("Adding pid %d to jdwp process list", proc->pid);
             jdwp_process_list_updated();
         }
         else
@@ -312,27 +312,27 @@
                     if (len < 0 && errno == EAGAIN)
                         return;
                     else {
-                        D("terminating JDWP %d connection: %s\n", proc->pid,
+                        D("terminating JDWP %d connection: %s", proc->pid,
                           strerror(errno));
                         break;
                     }
                 }
                 else {
-                    D( "ignoring unexpected JDWP %d control socket activity (%d bytes)\n",
+                    D( "ignoring unexpected JDWP %d control socket activity (%d bytes)",
                        proc->pid, len );
                 }
             }
 
         CloseProcess:
             if (proc->pid >= 0)
-                D( "remove pid %d to jdwp process list\n", proc->pid );
+                D( "remove pid %d to jdwp process list", proc->pid );
             jdwp_process_free(proc);
             return;
         }
     }
 
     if (events & FDE_WRITE) {
-        D("trying to write to JDWP pid controli (count=%d first=%d) %d\n",
+        D("trying to write to JDWP pid controli (count=%d first=%d) %d",
           proc->pid, proc->out_count, proc->out_fds[0]);
         if (proc->out_count > 0) {
             int  fd = proc->out_fds[0];
@@ -363,14 +363,14 @@
             flags = fcntl(proc->socket,F_GETFL,0);
 
             if (flags == -1) {
-                D("failed to get cntl flags for socket %d: %s\n",
+                D("failed to get cntl flags for socket %d: %s",
                   proc->pid, strerror(errno));
                 goto CloseProcess;
 
             }
 
             if (fcntl(proc->socket, F_SETFL, flags & ~O_NONBLOCK) == -1) {
-                D("failed to remove O_NONBLOCK flag for socket %d: %s\n",
+                D("failed to remove O_NONBLOCK flag for socket %d: %s",
                   proc->pid, strerror(errno));
                 goto CloseProcess;
             }
@@ -383,19 +383,19 @@
                 }
                 if (errno == EINTR)
                     continue;
-                D("sending new file descriptor to JDWP %d failed: %s\n",
+                D("sending new file descriptor to JDWP %d failed: %s",
                   proc->pid, strerror(errno));
                 goto CloseProcess;
             }
 
-            D("sent file descriptor %d to JDWP process %d\n",
+            D("sent file descriptor %d to JDWP process %d",
               fd, proc->pid);
 
             for (n = 1; n < proc->out_count; n++)
                 proc->out_fds[n-1] = proc->out_fds[n];
 
             if (fcntl(proc->socket, F_SETFL, flags) == -1) {
-                D("failed to set O_NONBLOCK flag for socket %d: %s\n",
+                D("failed to set O_NONBLOCK flag for socket %d: %s",
                   proc->pid, strerror(errno));
                 goto CloseProcess;
             }
@@ -412,13 +412,13 @@
 {
     JdwpProcess*  proc = _jdwp_list.next;
 
-    D("looking for pid %d in JDWP process list\n", pid);
+    D("looking for pid %d in JDWP process list", pid);
     for ( ; proc != &_jdwp_list; proc = proc->next ) {
         if (proc->pid == pid) {
             goto FoundIt;
         }
     }
-    D("search failed !!\n");
+    D("search failed !!");
     return -1;
 
 FoundIt:
@@ -426,17 +426,17 @@
         int  fds[2];
 
         if (proc->out_count >= MAX_OUT_FDS) {
-            D("%s: too many pending JDWP connection for pid %d\n",
+            D("%s: too many pending JDWP connection for pid %d",
               __FUNCTION__, pid);
             return -1;
         }
 
         if (adb_socketpair(fds) < 0) {
-            D("%s: socket pair creation failed: %s\n",
+            D("%s: socket pair creation failed: %s",
               __FUNCTION__, strerror(errno));
             return -1;
         }
-        D("socketpair: (%d,%d)\n", fds[0], fds[1]);
+        D("socketpair: (%d,%d)", fds[0], fds[1]);
 
         proc->out_fds[ proc->out_count ] = fds[1];
         if (++proc->out_count == 1)
@@ -477,7 +477,7 @@
     int                  pathlen = socknamelen;
 
     if (pathlen >= maxpath) {
-        D( "vm debug control socket name too long (%d extra chars)\n",
+        D( "vm debug control socket name too long (%d extra chars)",
            pathlen+1-maxpath );
         return -1;
     }
@@ -488,7 +488,7 @@
 
     s = socket( AF_UNIX, SOCK_STREAM, 0 );
     if (s < 0) {
-        D( "could not create vm debug control socket. %d: %s\n",
+        D( "could not create vm debug control socket. %d: %s",
            errno, strerror(errno));
         return -1;
     }
@@ -496,14 +496,14 @@
     addrlen = (pathlen + sizeof(addr.sun_family));
 
     if (bind(s, (struct sockaddr*)&addr, addrlen) < 0) {
-        D( "could not bind vm debug control socket: %d: %s\n",
+        D( "could not bind vm debug control socket: %d: %s",
            errno, strerror(errno) );
         adb_close(s);
         return -1;
     }
 
     if ( listen(s, 4) < 0 ) {
-        D("listen failed in jdwp control socket: %d: %s\n",
+        D("listen failed in jdwp control socket: %d: %s",
           errno, strerror(errno));
         adb_close(s);
         return -1;
@@ -513,7 +513,7 @@
 
     control->fde = fdevent_create(s, jdwp_control_event, control);
     if (control->fde == NULL) {
-        D( "could not create fdevent for jdwp control socket\n" );
+        D( "could not create fdevent for jdwp control socket" );
         adb_close(s);
         return -1;
     }
@@ -522,7 +522,7 @@
     fdevent_add(control->fde, FDE_READ);
     close_on_exec(s);
 
-    D("jdwp control socket started (%d)\n", control->listen_socket);
+    D("jdwp control socket started (%d)", control->listen_socket);
     return 0;
 }
 
@@ -545,11 +545,11 @@
                     continue;
                 if (errno == ECONNABORTED) {
                     /* oops, the JDWP process died really quick */
-                    D("oops, the JDWP process died really quick\n");
+                    D("oops, the JDWP process died really quick");
                     return;
                 }
                 /* the socket is probably closed ? */
-                D( "weird accept() failed on jdwp control socket: %s\n",
+                D( "weird accept() failed on jdwp control socket: %s",
                    strerror(errno) );
                 return;
             }
diff --git a/adb/mutex_list.h b/adb/mutex_list.h
index 9003361..79c48d8 100644
--- a/adb/mutex_list.h
+++ b/adb/mutex_list.h
@@ -14,13 +14,4 @@
 #endif
 ADB_MUTEX(usb_lock)
 
-// Sadly logging to /data/adb/adb-... is not thread safe.
-//  After modifying adb.h::D() to count invocations:
-//   DEBUG(jpa):0:Handling main()
-//   DEBUG(jpa):1:[ usb_init - starting thread ]
-// (Oopsies, no :2:, and matching message is also gone.)
-//   DEBUG(jpa):3:[ usb_thread - opening device ]
-//   DEBUG(jpa):4:jdwp control socket started (10)
-ADB_MUTEX(D_lock)
-
 #undef ADB_MUTEX
diff --git a/adb/services.cpp b/adb/services.cpp
index 4606804..561431c 100644
--- a/adb/services.cpp
+++ b/adb/services.cpp
@@ -24,11 +24,6 @@
 #include <stdlib.h>
 #include <string.h>
 
-#if !ADB_HOST
-#include <pty.h>
-#include <termios.h>
-#endif
-
 #ifndef _WIN32
 #include <netdb.h>
 #include <netinet/in.h>
@@ -51,6 +46,7 @@
 #include "adb_utils.h"
 #include "file_sync_service.h"
 #include "remount_service.h"
+#include "shell_service.h"
 #include "transport.h"
 
 struct stinfo {
@@ -59,11 +55,6 @@
     void *cookie;
 };
 
-enum class SubprocessType {
-    kPty,
-    kRaw,
-};
-
 void *service_bootstrap_func(void *x)
 {
     stinfo* sti = reinterpret_cast<stinfo*>(x);
@@ -147,7 +138,7 @@
         const char* const command_file = "/cache/recovery/command";
         // Ensure /cache/recovery exists.
         if (adb_mkdir(recovery_dir, 0770) == -1 && errno != EEXIST) {
-            D("Failed to create directory '%s': %s\n", recovery_dir, strerror(errno));
+            D("Failed to create directory '%s': %s", recovery_dir, strerror(errno));
             return false;
         }
 
@@ -212,7 +203,7 @@
         printf("cannot create service socket pair\n");
         return -1;
     }
-    D("socketpair: (%d,%d)\n", s[0], s[1]);
+    D("socketpair: (%d,%d)", s[0], s[1]);
 
     stinfo* sti = reinterpret_cast<stinfo*>(malloc(sizeof(stinfo)));
     if (sti == nullptr) {
@@ -230,215 +221,10 @@
         return -1;
     }
 
-    D("service thread started, %d:%d\n",s[0], s[1]);
+    D("service thread started, %d:%d",s[0], s[1]);
     return s[0];
 }
 
-#if !ADB_HOST
-
-static void init_subproc_child()
-{
-    setsid();
-
-    // Set OOM score adjustment to prevent killing
-    int fd = adb_open("/proc/self/oom_score_adj", O_WRONLY | O_CLOEXEC);
-    if (fd >= 0) {
-        adb_write(fd, "0", 1);
-        adb_close(fd);
-    } else {
-       D("adb: unable to update oom_score_adj\n");
-    }
-}
-
-#if !ADB_HOST
-static int create_subproc_pty(const char* cmd, const char* arg0,
-                              const char* arg1, pid_t* pid) {
-    D("create_subproc_pty(cmd=%s, arg0=%s, arg1=%s)\n", cmd, arg0, arg1);
-    char pts_name[PATH_MAX];
-    int ptm;
-    *pid = forkpty(&ptm, pts_name, nullptr, nullptr);
-    if (*pid == -1) {
-        printf("- fork failed: %s -\n", strerror(errno));
-        unix_close(ptm);
-        return -1;
-    }
-
-    if (*pid == 0) {
-        init_subproc_child();
-
-        int pts = unix_open(pts_name, O_RDWR | O_CLOEXEC);
-        if (pts == -1) {
-            fprintf(stderr, "child failed to open pseudo-term slave %s: %s\n",
-                    pts_name, strerror(errno));
-            unix_close(ptm);
-            exit(-1);
-        }
-
-        // arg0 is "-c" in batch mode and "-" in interactive mode.
-        if (strcmp(arg0, "-c") == 0) {
-            termios tattr;
-            if (tcgetattr(pts, &tattr) == -1) {
-                fprintf(stderr, "tcgetattr failed: %s\n", strerror(errno));
-                unix_close(pts);
-                unix_close(ptm);
-                exit(-1);
-            }
-
-            cfmakeraw(&tattr);
-            if (tcsetattr(pts, TCSADRAIN, &tattr) == -1) {
-                fprintf(stderr, "tcsetattr failed: %s\n", strerror(errno));
-                unix_close(pts);
-                unix_close(ptm);
-                exit(-1);
-            }
-        }
-
-        dup2(pts, STDIN_FILENO);
-        dup2(pts, STDOUT_FILENO);
-        dup2(pts, STDERR_FILENO);
-
-        unix_close(pts);
-        unix_close(ptm);
-
-        execl(cmd, cmd, arg0, arg1, nullptr);
-        fprintf(stderr, "- exec '%s' failed: %s (%d) -\n",
-                cmd, strerror(errno), errno);
-        exit(-1);
-    } else {
-        return ptm;
-    }
-}
-#endif // !ADB_HOST
-
-static int create_subproc_raw(const char *cmd, const char *arg0, const char *arg1, pid_t *pid)
-{
-    D("create_subproc_raw(cmd=%s, arg0=%s, arg1=%s)\n", cmd, arg0, arg1);
-#if defined(_WIN32)
-    fprintf(stderr, "error: create_subproc_raw not implemented on Win32 (%s %s %s)\n", cmd, arg0, arg1);
-    return -1;
-#else
-
-    // 0 is parent socket, 1 is child socket
-    int sv[2];
-    if (adb_socketpair(sv) < 0) {
-        printf("[ cannot create socket pair - %s ]\n", strerror(errno));
-        return -1;
-    }
-    D("socketpair: (%d,%d)\n", sv[0], sv[1]);
-
-    *pid = fork();
-    if (*pid < 0) {
-        printf("- fork failed: %s -\n", strerror(errno));
-        adb_close(sv[0]);
-        adb_close(sv[1]);
-        return -1;
-    }
-
-    if (*pid == 0) {
-        adb_close(sv[0]);
-        init_subproc_child();
-
-        dup2(sv[1], STDIN_FILENO);
-        dup2(sv[1], STDOUT_FILENO);
-        dup2(sv[1], STDERR_FILENO);
-
-        adb_close(sv[1]);
-
-        execl(cmd, cmd, arg0, arg1, NULL);
-        fprintf(stderr, "- exec '%s' failed: %s (%d) -\n",
-                cmd, strerror(errno), errno);
-        exit(-1);
-    } else {
-        adb_close(sv[1]);
-        return sv[0];
-    }
-#endif /* !defined(_WIN32) */
-}
-#endif  /* !ABD_HOST */
-
-#if ADB_HOST
-#define SHELL_COMMAND "/bin/sh"
-#else
-#define SHELL_COMMAND "/system/bin/sh"
-#endif
-
-#if !ADB_HOST
-static void subproc_waiter_service(int fd, void *cookie)
-{
-    pid_t pid = (pid_t) (uintptr_t) cookie;
-
-    D("entered. fd=%d of pid=%d\n", fd, pid);
-    while (true) {
-        int status;
-        pid_t p = waitpid(pid, &status, 0);
-        if (p == pid) {
-            D("fd=%d, post waitpid(pid=%d) status=%04x\n", fd, p, status);
-            if (WIFSIGNALED(status)) {
-                D("*** Killed by signal %d\n", WTERMSIG(status));
-                break;
-            } else if (!WIFEXITED(status)) {
-                D("*** Didn't exit!!. status %d\n", status);
-                break;
-            } else if (WEXITSTATUS(status) >= 0) {
-                D("*** Exit code %d\n", WEXITSTATUS(status));
-                break;
-            }
-         }
-    }
-    D("shell exited fd=%d of pid=%d err=%d\n", fd, pid, errno);
-    if (SHELL_EXIT_NOTIFY_FD >=0) {
-      int res;
-      res = WriteFdExactly(SHELL_EXIT_NOTIFY_FD, &fd, sizeof(fd)) ? 0 : -1;
-      D("notified shell exit via fd=%d for pid=%d res=%d errno=%d\n",
-        SHELL_EXIT_NOTIFY_FD, pid, res, errno);
-    }
-}
-
-// Starts a subprocess and spawns a thread to wait for the subprocess to finish
-// and trigger the necessary cleanup.
-//
-// |name| is the command to execute in the subprocess; empty string will start
-//     an interactive session.
-// |type| selects between a PTY or raw subprocess.
-//
-// Returns an open file descriptor tied to the subprocess stdin/stdout/stderr.
-static int create_subproc_thread(const char *name, SubprocessType type) {
-    const char *arg0, *arg1;
-    if (*name == '\0') {
-        arg0 = "-";
-        arg1 = nullptr;
-    } else {
-        arg0 = "-c";
-        arg1 = name;
-    }
-
-    pid_t pid = -1;
-    int ret_fd;
-    if (type == SubprocessType::kPty) {
-        ret_fd = create_subproc_pty(SHELL_COMMAND, arg0, arg1, &pid);
-    } else {
-        ret_fd = create_subproc_raw(SHELL_COMMAND, arg0, arg1, &pid);
-    }
-    D("create_subproc ret_fd=%d pid=%d\n", ret_fd, pid);
-
-    stinfo* sti = reinterpret_cast<stinfo*>(malloc(sizeof(stinfo)));
-    if(sti == 0) fatal("cannot allocate stinfo");
-    sti->func = subproc_waiter_service;
-    sti->cookie = (void*) (uintptr_t) pid;
-    sti->fd = ret_fd;
-
-    if (!adb_thread_create(service_bootstrap_func, sti)) {
-        free(sti);
-        adb_close(ret_fd);
-        fprintf(stderr, "cannot create service thread\n");
-        return -1;
-    }
-
-    D("service thread started, fd=%d pid=%d\n", ret_fd, pid);
-    return ret_fd;
-}
-#endif
-
 int service_to_fd(const char* name) {
     int ret = -1;
 
@@ -483,13 +269,13 @@
         const char* args = name + 6;
         if (*args) {
             // Non-interactive session uses a raw subprocess.
-            ret = create_subproc_thread(args, SubprocessType::kRaw);
+            ret = StartSubprocess(args, SubprocessType::kRaw);
         } else {
             // Interactive session uses a PTY subprocess.
-            ret = create_subproc_thread(args, SubprocessType::kPty);
+            ret = StartSubprocess(args, SubprocessType::kPty);
         }
     } else if(!strncmp(name, "exec:", 5)) {
-        ret = create_subproc_thread(name + 5, SubprocessType::kRaw);
+        ret = StartSubprocess(name + 5, SubprocessType::kRaw);
     } else if(!strncmp(name, "sync:", 5)) {
         ret = create_service_thread(file_sync_service, NULL);
     } else if(!strncmp(name, "remount:", 8)) {
@@ -503,11 +289,11 @@
     } else if(!strncmp(name, "unroot:", 7)) {
         ret = create_service_thread(restart_unroot_service, NULL);
     } else if(!strncmp(name, "backup:", 7)) {
-        ret = create_subproc_thread(android::base::StringPrintf("/system/bin/bu backup %s",
-                                                                (name + 7)).c_str(),
-                                    SubprocessType::kRaw);
+        ret = StartSubprocess(android::base::StringPrintf("/system/bin/bu backup %s",
+                                                          (name + 7)).c_str(),
+                              SubprocessType::kRaw);
     } else if(!strncmp(name, "restore:", 8)) {
-        ret = create_subproc_thread("/system/bin/bu restore", SubprocessType::kRaw);
+        ret = StartSubprocess("/system/bin/bu restore", SubprocessType::kRaw);
     } else if(!strncmp(name, "tcpip:", 6)) {
         int port;
         if (sscanf(name + 6, "%d", &port) != 1) {
@@ -549,7 +335,7 @@
 {
     state_info* sinfo = reinterpret_cast<state_info*>(cookie);
 
-    D("wait_for_state %d\n", sinfo->state);
+    D("wait_for_state %d", sinfo->state);
 
     std::string error_msg = "unknown error";
     atransport* t = acquire_one_transport(sinfo->state, sinfo->transport_type, sinfo->serial,
@@ -564,7 +350,7 @@
         free(sinfo->serial);
     free(sinfo);
     adb_close(fd);
-    D("wait_for_state is done\n");
+    D("wait_for_state is done");
 }
 
 static void connect_device(const std::string& address, std::string* response) {
@@ -588,7 +374,7 @@
         return;
     }
 
-    D("client: connected %s remote on fd %d\n", serial.c_str(), fd);
+    D("client: connected %s remote on fd %d", serial.c_str(), fd);
     close_on_exec(fd);
     disable_tcp_nagle(fd);
 
diff --git a/adb/shell_service.cpp b/adb/shell_service.cpp
new file mode 100644
index 0000000..5f80a59
--- /dev/null
+++ b/adb/shell_service.cpp
@@ -0,0 +1,329 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define TRACE_TAG TRACE_SHELL
+
+#include "shell_service.h"
+
+#if !ADB_HOST
+
+#include <errno.h>
+#include <pty.h>
+#include <termios.h>
+
+#include <base/logging.h>
+#include <base/stringprintf.h>
+#include <paths.h>
+
+#include "adb.h"
+#include "adb_io.h"
+#include "adb_trace.h"
+#include "sysdeps.h"
+
+namespace {
+
+void init_subproc_child()
+{
+    setsid();
+
+    // Set OOM score adjustment to prevent killing
+    int fd = adb_open("/proc/self/oom_score_adj", O_WRONLY | O_CLOEXEC);
+    if (fd >= 0) {
+        adb_write(fd, "0", 1);
+        adb_close(fd);
+    } else {
+       D("adb: unable to update oom_score_adj");
+    }
+}
+
+// Reads from |fd| until close or failure.
+std::string ReadAll(int fd) {
+    char buffer[512];
+    std::string received;
+
+    while (1) {
+        int bytes = adb_read(fd, buffer, sizeof(buffer));
+        if (bytes <= 0) {
+            break;
+        }
+        received.append(buffer, bytes);
+    }
+
+    return received;
+}
+
+// Helper to automatically close an FD when it goes out of scope.
+class ScopedFd {
+  public:
+    ScopedFd() {}
+    ~ScopedFd() { Reset(); }
+
+    void Reset(int fd=-1) {
+        if (fd != fd_) {
+            if (valid()) {
+                adb_close(fd_);
+            }
+            fd_ = fd;
+        }
+    }
+
+    int Release() {
+        int temp = fd_;
+        fd_ = -1;
+        return temp;
+    }
+
+    bool valid() const { return fd_ >= 0; }
+
+    int fd() const { return fd_; }
+
+  private:
+    int fd_ = -1;
+
+    DISALLOW_COPY_AND_ASSIGN(ScopedFd);
+};
+
+// Creates a socketpair and saves the endpoints to |fd1| and |fd2|.
+bool CreateSocketpair(ScopedFd* fd1, ScopedFd* fd2) {
+    int sockets[2];
+    if (adb_socketpair(sockets) < 0) {
+        PLOG(ERROR) << "cannot create socket pair";
+        return false;
+    }
+    fd1->Reset(sockets[0]);
+    fd2->Reset(sockets[1]);
+    return true;
+}
+
+class Subprocess {
+  public:
+    Subprocess(const std::string& command, SubprocessType type);
+    ~Subprocess();
+
+    const std::string& command() const { return command_; }
+    bool is_interactive() const { return command_.empty(); }
+
+    int local_socket_fd() const { return local_socket_sfd_.fd(); }
+
+    pid_t pid() const { return pid_; }
+
+    // Sets up FDs, forks a subprocess, starts the subprocess manager thread,
+    // and exec's the child. Returns false on failure.
+    bool ForkAndExec();
+
+  private:
+    // Opens the file at |pts_name|.
+    int OpenPtyChildFd(const char* pts_name, ScopedFd* error_sfd);
+
+    static void* ThreadHandler(void* userdata);
+    void WaitForExit();
+
+    const std::string command_;
+    SubprocessType type_;
+
+    pid_t pid_ = -1;
+    ScopedFd local_socket_sfd_;
+
+    DISALLOW_COPY_AND_ASSIGN(Subprocess);
+};
+
+Subprocess::Subprocess(const std::string& command, SubprocessType type)
+        : command_(command), type_(type) {
+}
+
+Subprocess::~Subprocess() {
+}
+
+bool Subprocess::ForkAndExec() {
+    ScopedFd parent_sfd, child_sfd, parent_error_sfd, child_error_sfd;
+    char pts_name[PATH_MAX];
+
+    // Create a socketpair for the fork() child to report any errors back to
+    // the parent. Since we use threads, logging directly from the child could
+    // create a race condition.
+    if (!CreateSocketpair(&parent_error_sfd, &child_error_sfd)) {
+        LOG(ERROR) << "failed to create pipe for subprocess error reporting";
+    }
+
+    if (type_ == SubprocessType::kPty) {
+        int fd;
+        pid_ = forkpty(&fd, pts_name, nullptr, nullptr);
+        parent_sfd.Reset(fd);
+    } else {
+        if (!CreateSocketpair(&parent_sfd, &child_sfd)) {
+            return false;
+        }
+        pid_ = fork();
+    }
+
+    if (pid_ == -1) {
+        PLOG(ERROR) << "fork failed";
+        return false;
+    }
+
+    if (pid_ == 0) {
+        // Subprocess child.
+        init_subproc_child();
+
+        if (type_ == SubprocessType::kPty) {
+            child_sfd.Reset(OpenPtyChildFd(pts_name, &child_error_sfd));
+        }
+
+        dup2(child_sfd.fd(), STDIN_FILENO);
+        dup2(child_sfd.fd(), STDOUT_FILENO);
+        dup2(child_sfd.fd(), STDERR_FILENO);
+
+        // exec doesn't trigger destructors, close the FDs manually.
+        parent_sfd.Reset();
+        child_sfd.Reset();
+        parent_error_sfd.Reset();
+        close_on_exec(child_error_sfd.fd());
+
+        if (is_interactive()) {
+            execl(_PATH_BSHELL, _PATH_BSHELL, "-", nullptr);
+        } else {
+            execl(_PATH_BSHELL, _PATH_BSHELL, "-c", command_.c_str(), nullptr);
+        }
+        WriteFdExactly(child_error_sfd.fd(), "exec '" _PATH_BSHELL "' failed");
+        child_error_sfd.Reset();
+        exit(-1);
+    }
+
+    // Subprocess parent.
+    D("subprocess parent: subprocess FD = %d", parent_sfd.fd());
+
+    // Wait to make sure the subprocess exec'd without error.
+    child_error_sfd.Reset();
+    std::string error_message = ReadAll(parent_error_sfd.fd());
+    if (!error_message.empty()) {
+        LOG(ERROR) << error_message;
+        return false;
+    }
+
+    local_socket_sfd_.Reset(parent_sfd.Release());
+
+    if (!adb_thread_create(ThreadHandler, this)) {
+        PLOG(ERROR) << "failed to create subprocess thread";
+        return false;
+    }
+
+    return true;
+}
+
+int Subprocess::OpenPtyChildFd(const char* pts_name, ScopedFd* error_sfd) {
+    int child_fd = adb_open(pts_name, O_RDWR | O_CLOEXEC);
+    if (child_fd == -1) {
+        // Don't use WriteFdFmt; since we're in the fork() child we don't want
+        // to allocate any heap memory to avoid race conditions.
+        const char* messages[] = {"child failed to open pseudo-term slave ",
+                                  pts_name, ": ", strerror(errno)};
+        for (const char* message : messages) {
+            WriteFdExactly(error_sfd->fd(), message);
+        }
+        exit(-1);
+    }
+
+    if (!is_interactive()) {
+        termios tattr;
+        if (tcgetattr(child_fd, &tattr) == -1) {
+            WriteFdExactly(error_sfd->fd(), "tcgetattr failed");
+            exit(-1);
+        }
+
+        cfmakeraw(&tattr);
+        if (tcsetattr(child_fd, TCSADRAIN, &tattr) == -1) {
+            WriteFdExactly(error_sfd->fd(), "tcsetattr failed");
+            exit(-1);
+        }
+    }
+
+    return child_fd;
+}
+
+void* Subprocess::ThreadHandler(void* userdata) {
+    Subprocess* subprocess = reinterpret_cast<Subprocess*>(userdata);
+
+    adb_thread_setname(android::base::StringPrintf(
+            "shell srvc %d", subprocess->local_socket_fd()));
+
+    subprocess->WaitForExit();
+
+    D("deleting Subprocess");
+    delete subprocess;
+
+    return nullptr;
+}
+
+void Subprocess::WaitForExit() {
+    D("waiting for pid %d", pid_);
+    while (true) {
+        int status;
+        if (pid_ == waitpid(pid_, &status, 0)) {
+            D("post waitpid (pid=%d) status=%04x", pid_, status);
+            if (WIFSIGNALED(status)) {
+                D("subprocess killed by signal %d", WTERMSIG(status));
+                break;
+            } else if (!WIFEXITED(status)) {
+                D("subprocess didn't exit");
+                break;
+            } else if (WEXITSTATUS(status) >= 0) {
+                D("subprocess exit code = %d", WEXITSTATUS(status));
+                break;
+            }
+        }
+    }
+
+    // Pass the local socket FD to the shell cleanup fdevent.
+    if (SHELL_EXIT_NOTIFY_FD >= 0) {
+        int fd = local_socket_sfd_.fd();
+        if (WriteFdExactly(SHELL_EXIT_NOTIFY_FD, &fd, sizeof(fd))) {
+            D("passed fd %d to SHELL_EXIT_NOTIFY_FD (%d) for pid %d",
+              fd, SHELL_EXIT_NOTIFY_FD, pid_);
+            // The shell exit fdevent now owns the FD and will close it once
+            // the last bit of data flushes through.
+            local_socket_sfd_.Release();
+        } else {
+            PLOG(ERROR) << "failed to write fd " << fd
+                        << " to SHELL_EXIT_NOTIFY_FD (" << SHELL_EXIT_NOTIFY_FD
+                        << ") for pid " << pid_;
+        }
+    }
+}
+
+}  // namespace
+
+int StartSubprocess(const char *name, SubprocessType type) {
+    D("starting %s subprocess: '%s'",
+      type == SubprocessType::kRaw ? "raw" : "PTY", name);
+
+    Subprocess* subprocess = new Subprocess(name, type);
+    if (!subprocess) {
+        LOG(ERROR) << "failed to allocate new subprocess";
+        return -1;
+    }
+
+    if (!subprocess->ForkAndExec()) {
+        LOG(ERROR) << "failed to start subprocess";
+        delete subprocess;
+        return -1;
+    }
+
+    D("subprocess creation successful: local_socket_fd=%d, pid=%d",
+      subprocess->local_socket_fd(), subprocess->pid());
+    return subprocess->local_socket_fd();
+}
+
+#endif  // !ADB_HOST
diff --git a/adb/shell_service.h b/adb/shell_service.h
new file mode 100644
index 0000000..c2a048c
--- /dev/null
+++ b/adb/shell_service.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SHELL_SERVICE_H_
+#define SHELL_SERVICE_H_
+
+#if !ADB_HOST
+
+enum class SubprocessType {
+    kPty,
+    kRaw,
+};
+
+// Forks and starts a new shell subprocess. If |name| is empty an interactive
+// shell is started, otherwise |name| is executed non-interactively.
+//
+// Returns an open FD connected to the subprocess or -1 on failure.
+int StartSubprocess(const char* name, SubprocessType type);
+
+#endif  // !ADB_HOST
+
+#endif  // SHELL_SERVICE_H_
diff --git a/adb/sockets.cpp b/adb/sockets.cpp
index 9c13936..f8c22cc 100644
--- a/adb/sockets.cpp
+++ b/adb/sockets.cpp
@@ -133,7 +133,7 @@
 
 static int local_socket_enqueue(asocket *s, apacket *p)
 {
-    D("LS(%d): enqueue %d\n", s->id, p->len);
+    D("LS(%d): enqueue %d", s->id, p->len);
 
     p->ptr = p->data;
 
@@ -156,7 +156,7 @@
             continue;
         }
         if((r == 0) || (errno != EAGAIN)) {
-            D( "LS(%d): not ready, errno=%d: %s\n", s->id, errno, strerror(errno) );
+            D( "LS(%d): not ready, errno=%d: %s", s->id, errno, strerror(errno) );
             s->close(s);
             return 1; /* not ready (error) */
         } else {
@@ -204,7 +204,7 @@
     apacket *p, *n;
     int exit_on_close = s->exit_on_close;
 
-    D("LS(%d): destroying fde.fd=%d\n", s->id, s->fde.fd);
+    D("LS(%d): destroying fde.fd=%d", s->id, s->fde.fd);
 
         /* IMPORTANT: the remove closes the fd
         ** that belongs to this socket
@@ -213,7 +213,7 @@
 
         /* dispose of any unwritten data */
     for(p = s->pkt_first; p; p = n) {
-        D("LS(%d): discarding %d bytes\n", s->id, p->len);
+        D("LS(%d): discarding %d bytes", s->id, p->len);
         n = p->next;
         put_apacket(p);
     }
@@ -221,7 +221,7 @@
     free(s);
 
     if (exit_on_close) {
-        D("local_socket_destroy: exiting\n");
+        D("local_socket_destroy: exiting");
         exit(1);
     }
 }
@@ -229,9 +229,9 @@
 
 static void local_socket_close_locked(asocket *s)
 {
-    D("entered local_socket_close_locked. LS(%d) fd=%d\n", s->id, s->fd);
+    D("entered local_socket_close_locked. LS(%d) fd=%d", s->id, s->fd);
     if(s->peer) {
-        D("LS(%d): closing peer. peer->id=%d peer->fd=%d\n",
+        D("LS(%d): closing peer. peer->id=%d peer->fd=%d",
           s->id, s->peer->id, s->peer->fd);
         /* Note: it's important to call shutdown before disconnecting from
          * the peer, this ensures that remote sockets can still get the id
@@ -255,24 +255,24 @@
     if (s->closing || s->pkt_first == NULL) {
         int   id = s->id;
         local_socket_destroy(s);
-        D("LS(%d): closed\n", id);
+        D("LS(%d): closed", id);
         return;
     }
 
         /* otherwise, put on the closing list
         */
-    D("LS(%d): closing\n", s->id);
+    D("LS(%d): closing", s->id);
     s->closing = 1;
     fdevent_del(&s->fde, FDE_READ);
     remove_socket(s);
-    D("LS(%d): put on socket_closing_list fd=%d\n", s->id, s->fd);
+    D("LS(%d): put on socket_closing_list fd=%d", s->id, s->fd);
     insert_local_socket(s, &local_socket_closing_list);
 }
 
 static void local_socket_event_func(int fd, unsigned ev, void* _s)
 {
     asocket* s = reinterpret_cast<asocket*>(_s);
-    D("LS(%d): event_func(fd=%d(==%d), ev=%04x)\n", s->id, s->fd, fd, ev);
+    D("LS(%d): event_func(fd=%d(==%d), ev=%04x)", s->id, s->fd, fd, ev);
 
     /* put the FDE_WRITE processing before the FDE_READ
     ** in order to simplify the code.
@@ -295,7 +295,7 @@
                     continue;
                 }
 
-                D(" closing after write because r=%d and errno is %d\n", r, errno);
+                D(" closing after write because r=%d and errno is %d", r, errno);
                 s->close(s);
                 return;
             }
@@ -313,7 +313,7 @@
         ** we can now destroy it.
         */
         if (s->closing) {
-            D(" closing because 'closing' is set after write\n");
+            D(" closing because 'closing' is set after write");
             s->close(s);
             return;
         }
@@ -337,7 +337,7 @@
 
         while (avail > 0) {
             r = adb_read(fd, x, avail);
-            D("LS(%d): post adb_read(fd=%d,...) r=%d (errno=%d) avail=%zu\n",
+            D("LS(%d): post adb_read(fd=%d,...) r=%d (errno=%d) avail=%zu",
               s->id, s->fd, r, r < 0 ? errno : 0, avail);
             if (r == -1) {
                 if (errno == EAGAIN) {
@@ -353,7 +353,7 @@
             is_eof = 1;
             break;
         }
-        D("LS(%d): fd=%d post avail loop. r=%d is_eof=%d forced_eof=%d\n",
+        D("LS(%d): fd=%d post avail loop. r=%d is_eof=%d forced_eof=%d",
           s->id, s->fd, r, is_eof, s->fde.force_eof);
         if ((avail == max_payload) || (s->peer == 0)) {
             put_apacket(p);
@@ -365,7 +365,7 @@
             unsigned saved_id = s->id;
             int saved_fd = s->fd;
             r = s->peer->enqueue(s->peer, p);
-            D("LS(%u): fd=%d post peer->enqueue(). r=%d\n", saved_id, saved_fd, r);
+            D("LS(%u): fd=%d post peer->enqueue(). r=%d", saved_id, saved_fd, r);
 
             if (r < 0) {
                     /* error return means they closed us as a side-effect
@@ -389,7 +389,7 @@
         }
         /* Don't allow a forced eof if data is still there */
         if ((s->fde.force_eof && !r) || is_eof) {
-            D(" closing because is_eof=%d r=%d s->fde.force_eof=%d\n",
+            D(" closing because is_eof=%d r=%d s->fde.force_eof=%d",
               is_eof, r, s->fde.force_eof);
             s->close(s);
         }
@@ -400,7 +400,7 @@
             ** catching it here means we may skip the last few
             ** bytes of readable data.
             */
-        D("LS(%d): FDE_ERROR (fd=%d)\n", s->id, s->fd);
+        D("LS(%d): FDE_ERROR (fd=%d)", s->id, s->fd);
 
         return;
     }
@@ -418,7 +418,7 @@
     install_local_socket(s);
 
     fdevent_install(&s->fde, fd, local_socket_event_func, s);
-    D("LS(%d): created (fd=%d)\n", s->id, s->fd);
+    D("LS(%d): created (fd=%d)", s->id, s->fd);
     return s;
 }
 
@@ -436,7 +436,7 @@
     if(fd < 0) return 0;
 
     asocket* s = create_local_socket(fd);
-    D("LS(%d): bound to '%s' via %d\n", s->id, name, fd);
+    D("LS(%d): bound to '%s' via %d", s->id, name, fd);
 
 #if !ADB_HOST
     char debug[PROPERTY_VALUE_MAX];
@@ -447,7 +447,7 @@
         || (!strncmp(name, "unroot:", 7) && getuid() == 0)
         || !strncmp(name, "usb:", 4)
         || !strncmp(name, "tcpip:", 6)) {
-        D("LS(%d): enabling exit_on_close\n", s->id);
+        D("LS(%d): enabling exit_on_close", s->id);
         s->exit_on_close = 1;
     }
 #endif
@@ -463,7 +463,7 @@
     s = host_service_to_socket(name, serial);
 
     if (s != NULL) {
-        D("LS(%d) bound to '%s'\n", s->id, name);
+        D("LS(%d) bound to '%s'", s->id, name);
         return s;
     }
 
@@ -473,7 +473,7 @@
 
 static int remote_socket_enqueue(asocket *s, apacket *p)
 {
-    D("entered remote_socket_enqueue RS(%d) WRITE fd=%d peer.fd=%d\n",
+    D("entered remote_socket_enqueue RS(%d) WRITE fd=%d peer.fd=%d",
       s->id, s->fd, s->peer->fd);
     p->msg.command = A_WRTE;
     p->msg.arg0 = s->peer->id;
@@ -485,7 +485,7 @@
 
 static void remote_socket_ready(asocket *s)
 {
-    D("entered remote_socket_ready RS(%d) OKAY fd=%d peer.fd=%d\n",
+    D("entered remote_socket_ready RS(%d) OKAY fd=%d peer.fd=%d",
       s->id, s->fd, s->peer->fd);
     apacket *p = get_apacket();
     p->msg.command = A_OKAY;
@@ -496,7 +496,7 @@
 
 static void remote_socket_shutdown(asocket *s)
 {
-    D("entered remote_socket_shutdown RS(%d) CLOSE fd=%d peer->fd=%d\n",
+    D("entered remote_socket_shutdown RS(%d) CLOSE fd=%d peer->fd=%d",
       s->id, s->fd, s->peer?s->peer->fd:-1);
     apacket *p = get_apacket();
     p->msg.command = A_CLSE;
@@ -511,13 +511,13 @@
 {
     if (s->peer) {
         s->peer->peer = 0;
-        D("RS(%d) peer->close()ing peer->id=%d peer->fd=%d\n",
+        D("RS(%d) peer->close()ing peer->id=%d peer->fd=%d",
           s->id, s->peer->id, s->peer->fd);
         s->peer->close(s->peer);
     }
-    D("entered remote_socket_close RS(%d) CLOSE fd=%d peer->fd=%d\n",
+    D("entered remote_socket_close RS(%d) CLOSE fd=%d peer->fd=%d",
       s->id, s->fd, s->peer?s->peer->fd:-1);
-    D("RS(%d): closed\n", s->id);
+    D("RS(%d): closed", s->id);
     free(s);
 }
 
@@ -538,13 +538,13 @@
     s->close = remote_socket_close;
     s->transport = t;
 
-    D("RS(%d): created\n", s->id);
+    D("RS(%d): created", s->id);
     return s;
 }
 
 void connect_to_remote(asocket *s, const char *destination)
 {
-    D("Connect_to_remote call RS(%d) fd=%d\n", s->id, s->fd);
+    D("Connect_to_remote call RS(%d) fd=%d", s->id, s->fd);
     apacket *p = get_apacket();
     size_t len = strlen(destination) + 1;
 
@@ -552,7 +552,7 @@
         fatal("destination oversized");
     }
 
-    D("LS(%d): connect('%s')\n", s->id, destination);
+    D("LS(%d): connect('%s')", s->id, destination);
     p->msg.command = A_OPEN;
     p->msg.arg0 = s->id;
     p->msg.data_length = len;
@@ -671,14 +671,14 @@
     TransportType type = kTransportAny;
 #endif
 
-    D("SS(%d): enqueue %d\n", s->id, p->len);
+    D("SS(%d): enqueue %d", s->id, p->len);
 
     if(s->pkt_first == 0) {
         s->pkt_first = p;
         s->pkt_last = p;
     } else {
         if((s->pkt_first->len + p->len) > s->get_max_payload()) {
-            D("SS(%d): overflow\n", s->id);
+            D("SS(%d): overflow", s->id);
             put_apacket(p);
             goto fail;
         }
@@ -696,20 +696,20 @@
 
     len = unhex(p->data, 4);
     if((len < 1) ||  (len > 1024)) {
-        D("SS(%d): bad size (%d)\n", s->id, len);
+        D("SS(%d): bad size (%d)", s->id, len);
         goto fail;
     }
 
-    D("SS(%d): len is %d\n", s->id, len );
+    D("SS(%d): len is %d", s->id, len );
         /* can't do anything until we have the full header */
     if((len + 4) > p->len) {
-        D("SS(%d): waiting for %d more bytes\n", s->id, len+4 - p->len);
+        D("SS(%d): waiting for %d more bytes", s->id, len+4 - p->len);
         return 0;
     }
 
     p->data[len + 4] = 0;
 
-    D("SS(%d): '%s'\n", s->id, (char*) (p->data + 4));
+    D("SS(%d): '%s'", s->id, (char*) (p->data + 4));
 
 #if ADB_HOST
     service = (char *)p->data + 4;
@@ -747,11 +747,11 @@
             */
         if(handle_host_request(service, type, serial, s->peer->fd, s) == 0) {
                 /* XXX fail message? */
-            D( "SS(%d): handled host service '%s'\n", s->id, service );
+            D( "SS(%d): handled host service '%s'", s->id, service );
             goto fail;
         }
         if (!strncmp(service, "transport", strlen("transport"))) {
-            D( "SS(%d): okay transport\n", s->id );
+            D( "SS(%d): okay transport", s->id );
             p->len = 0;
             return 0;
         }
@@ -762,7 +762,7 @@
             */
         s2 = create_host_service_socket(service, serial);
         if(s2 == 0) {
-            D( "SS(%d): couldn't create host service '%s'\n", s->id, service );
+            D( "SS(%d): couldn't create host service '%s'", s->id, service );
             SendFail(s->peer->fd, "unknown host service");
             goto fail;
         }
@@ -782,7 +782,7 @@
         s->peer->peer = s2;
         s2->peer = s->peer;
         s->peer = 0;
-        D( "SS(%d): okay\n", s->id );
+        D( "SS(%d): okay", s->id );
         s->close(s);
 
             /* initial state is "ready" */
@@ -839,12 +839,12 @@
 
 static void smart_socket_ready(asocket *s)
 {
-    D("SS(%d): ready\n", s->id);
+    D("SS(%d): ready", s->id);
 }
 
 static void smart_socket_close(asocket *s)
 {
-    D("SS(%d): closed\n", s->id);
+    D("SS(%d): closed", s->id);
     if(s->pkt_first){
         put_apacket(s->pkt_first);
     }
@@ -858,7 +858,7 @@
 
 static asocket *create_smart_socket(void)
 {
-    D("Creating smart socket \n");
+    D("Creating smart socket");
     asocket *s = reinterpret_cast<asocket*>(calloc(1, sizeof(asocket)));
     if (s == NULL) fatal("cannot allocate socket");
     s->enqueue = smart_socket_enqueue;
@@ -866,13 +866,13 @@
     s->shutdown = NULL;
     s->close = smart_socket_close;
 
-    D("SS(%d)\n", s->id);
+    D("SS(%d)", s->id);
     return s;
 }
 
 void connect_to_smartsocket(asocket *s)
 {
-    D("Connecting to smart socket \n");
+    D("Connecting to smart socket");
     asocket *ss = create_smart_socket();
     s->peer = ss;
     ss->peer = s;
diff --git a/adb/sysdeps_win32.cpp b/adb/sysdeps_win32.cpp
index 015f89e..b53cd77 100644
--- a/adb/sysdeps_win32.cpp
+++ b/adb/sysdeps_win32.cpp
@@ -122,7 +122,7 @@
     // only need to check for INVALID_HANDLE_VALUE.
     if (h != INVALID_HANDLE_VALUE) {
         if (!CloseHandle(h)) {
-            D("CloseHandle(%p) failed: %s\n", h,
+            D("CloseHandle(%p) failed: %s", h,
               SystemErrorCodeToString(GetLastError()).c_str());
         }
     }
@@ -159,7 +159,7 @@
     if (file_size > 0) {
         data = (char*) malloc( file_size + 1 );
         if (data == NULL) {
-            D("load_file: could not allocate %ld bytes\n", file_size );
+            D("load_file: could not allocate %ld bytes", file_size );
             file_size = 0;
         } else {
             DWORD  out_bytes;
@@ -167,7 +167,7 @@
             if ( !ReadFile( file, data, file_size, &out_bytes, NULL ) ||
                  out_bytes != file_size )
             {
-                D("load_file: could not read %ld bytes from '%s'\n", file_size, fn);
+                D("load_file: could not read %ld bytes from '%s'", file_size, fn);
                 free(data);
                 data      = NULL;
                 file_size = 0;
@@ -229,7 +229,7 @@
     fd -= WIN32_FH_BASE;
 
     if (fd < 0 || fd >= WIN32_MAX_FHS) {
-        D( "_fh_from_int: invalid fd %d passed to %s\n", fd + WIN32_FH_BASE,
+        D( "_fh_from_int: invalid fd %d passed to %s", fd + WIN32_FH_BASE,
            func );
         errno = EBADF;
         return NULL;
@@ -238,7 +238,7 @@
     f = &_win32_fhs[fd];
 
     if (f->used == 0) {
-        D( "_fh_from_int: invalid fd %d passed to %s\n", fd + WIN32_FH_BASE,
+        D( "_fh_from_int: invalid fd %d passed to %s", fd + WIN32_FH_BASE,
            func );
         errno = EBADF;
         return NULL;
@@ -278,7 +278,7 @@
             goto Exit;
         }
     }
-    D( "_fh_alloc: no more free file descriptors\n" );
+    D( "_fh_alloc: no more free file descriptors" );
     errno = EMFILE;   // Too many open files
 Exit:
     if (f) {
@@ -349,7 +349,7 @@
     DWORD  read_bytes;
 
     if ( !ReadFile( f->fh_handle, buf, (DWORD)len, &read_bytes, NULL ) ) {
-        D( "adb_read: could not read %d bytes from %s\n", len, f->name );
+        D( "adb_read: could not read %d bytes from %s", len, f->name );
         errno = EIO;
         return -1;
     } else if (read_bytes < (DWORD)len) {
@@ -362,7 +362,7 @@
     DWORD  wrote_bytes;
 
     if ( !WriteFile( f->fh_handle, buf, (DWORD)len, &wrote_bytes, NULL ) ) {
-        D( "adb_file_write: could not write %d bytes from %s\n", len, f->name );
+        D( "adb_file_write: could not write %d bytes from %s", len, f->name );
         errno = EIO;
         return -1;
     } else if (wrote_bytes < (DWORD)len) {
@@ -422,7 +422,7 @@
             desiredAccess = GENERIC_READ | GENERIC_WRITE;
             break;
         default:
-            D("adb_open: invalid options (0x%0x)\n", options);
+            D("adb_open: invalid options (0x%0x)", options);
             errno = EINVAL;
             return -1;
     }
@@ -441,17 +441,17 @@
         D( "adb_open: could not open '%s': ", path );
         switch (err) {
             case ERROR_FILE_NOT_FOUND:
-                D( "file not found\n" );
+                D( "file not found" );
                 errno = ENOENT;
                 return -1;
 
             case ERROR_PATH_NOT_FOUND:
-                D( "path not found\n" );
+                D( "path not found" );
                 errno = ENOTDIR;
                 return -1;
 
             default:
-                D( "unknown error: %s\n",
+                D( "unknown error: %s",
                    SystemErrorCodeToString( err ).c_str() );
                 errno = ENOENT;
                 return -1;
@@ -459,7 +459,7 @@
     }
 
     snprintf( f->name, sizeof(f->name), "%d(%s)", _fh_to_int(f), path );
-    D( "adb_open: '%s' => fd %d\n", path, _fh_to_int(f) );
+    D( "adb_open: '%s' => fd %d", path, _fh_to_int(f) );
     return _fh_to_int(f);
 }
 
@@ -484,24 +484,24 @@
         D( "adb_creat: could not open '%s': ", path );
         switch (err) {
             case ERROR_FILE_NOT_FOUND:
-                D( "file not found\n" );
+                D( "file not found" );
                 errno = ENOENT;
                 return -1;
 
             case ERROR_PATH_NOT_FOUND:
-                D( "path not found\n" );
+                D( "path not found" );
                 errno = ENOTDIR;
                 return -1;
 
             default:
-                D( "unknown error: %s\n",
+                D( "unknown error: %s",
                    SystemErrorCodeToString( err ).c_str() );
                 errno = ENOENT;
                 return -1;
         }
     }
     snprintf( f->name, sizeof(f->name), "%d(%s)", _fh_to_int(f), path );
-    D( "adb_creat: '%s' => fd %d\n", path, _fh_to_int(f) );
+    D( "adb_creat: '%s' => fd %d", path, _fh_to_int(f) );
     return _fh_to_int(f);
 }
 
@@ -550,7 +550,7 @@
         return -1;
     }
 
-    D( "adb_close: %s\n", f->name);
+    D( "adb_close: %s", f->name);
     _fh_close(f);
     return 0;
 }
@@ -580,7 +580,7 @@
     case WSAEMFILE:      errno = EMFILE; break;
     default:
         errno = EINVAL;
-        D( "_socket_set_errno: mapping Windows error code %lu to errno %d\n",
+        D( "_socket_set_errno: mapping Windows error code %lu to errno %d",
            err, errno );
     }
 }
@@ -589,7 +589,7 @@
     f->fh_socket = INVALID_SOCKET;
     f->event     = WSACreateEvent();
     if (f->event == WSA_INVALID_EVENT) {
-        D("WSACreateEvent failed: %s\n",
+        D("WSACreateEvent failed: %s",
           SystemErrorCodeToString(WSAGetLastError()).c_str());
 
         // _event_socket_start assumes that this field is INVALID_HANDLE_VALUE
@@ -608,19 +608,19 @@
             // If the socket is not connected, this returns an error. We want to
             // minimize logging spam, so don't log these errors for now.
 #if 0
-            D("socket shutdown failed: %s\n",
+            D("socket shutdown failed: %s",
               SystemErrorCodeToString(WSAGetLastError()).c_str());
 #endif
         }
         if (closesocket(f->fh_socket) == SOCKET_ERROR) {
-            D("closesocket failed: %s\n",
+            D("closesocket failed: %s",
               SystemErrorCodeToString(WSAGetLastError()).c_str());
         }
         f->fh_socket = INVALID_SOCKET;
     }
     if (f->event != NULL) {
         if (!CloseHandle(f->event)) {
-            D("CloseHandle failed: %s\n",
+            D("CloseHandle failed: %s",
               SystemErrorCodeToString(GetLastError()).c_str());
         }
         f->event = NULL;
@@ -641,7 +641,7 @@
         // WSAEWOULDBLOCK is normal with a non-blocking socket, so don't trace
         // that to reduce spam and confusion.
         if (err != WSAEWOULDBLOCK) {
-            D("recv fd %d failed: %s\n", _fh_to_int(f),
+            D("recv fd %d failed: %s", _fh_to_int(f),
               SystemErrorCodeToString(err).c_str());
         }
         _socket_set_errno(err);
@@ -654,7 +654,7 @@
     int  result = send(f->fh_socket, reinterpret_cast<const char*>(buf), len, 0);
     if (result == SOCKET_ERROR) {
         const DWORD err = WSAGetLastError();
-        D("send fd %d failed: %s\n", _fh_to_int(f),
+        D("send fd %d failed: %s", _fh_to_int(f),
           SystemErrorCodeToString(err).c_str());
         _socket_set_errno(err);
         result = -1;
@@ -726,7 +726,7 @@
     if(s == INVALID_SOCKET) {
         *error = android::base::StringPrintf("cannot create socket: %s",
                 SystemErrorCodeToString(WSAGetLastError()).c_str());
-        D("%s\n", error->c_str());
+        D("%s", error->c_str());
         return -1;
     }
     f->fh_socket = s;
@@ -737,7 +737,7 @@
         *error = android::base::StringPrintf("cannot connect to %s:%u: %s",
                 inet_ntoa(addr.sin_addr), ntohs(addr.sin_port),
                 SystemErrorCodeToString(err).c_str());
-        D("could not connect to %s:%d: %s\n",
+        D("could not connect to %s:%d: %s",
           type != SOCK_STREAM ? "udp" : "tcp", port, error->c_str());
         return -1;
     }
@@ -745,7 +745,7 @@
     const int fd = _fh_to_int(f.get());
     snprintf( f->name, sizeof(f->name), "%d(lo-client:%s%d)", fd,
               type != SOCK_STREAM ? "udp:" : "", port );
-    D( "port %d type %s => fd %d\n", port, type != SOCK_STREAM ? "udp" : "tcp",
+    D( "port %d type %s => fd %d", port, type != SOCK_STREAM ? "udp" : "tcp",
        fd );
     f.release();
     return fd;
@@ -780,7 +780,7 @@
     if (s == INVALID_SOCKET) {
         *error = android::base::StringPrintf("cannot create socket: %s",
                 SystemErrorCodeToString(WSAGetLastError()).c_str());
-        D("%s\n", error->c_str());
+        D("%s", error->c_str());
         return -1;
     }
 
@@ -794,7 +794,7 @@
         *error = android::base::StringPrintf(
                 "cannot set socket option SO_EXCLUSIVEADDRUSE: %s",
                 SystemErrorCodeToString(WSAGetLastError()).c_str());
-        D("%s\n", error->c_str());
+        D("%s", error->c_str());
         return -1;
     }
 
@@ -804,7 +804,7 @@
         *error = android::base::StringPrintf("cannot bind to %s:%u: %s",
                 inet_ntoa(addr.sin_addr), ntohs(addr.sin_port),
                 SystemErrorCodeToString(err).c_str());
-        D("could not bind to %s:%d: %s\n",
+        D("could not bind to %s:%d: %s",
           type != SOCK_STREAM ? "udp" : "tcp", port, error->c_str());
         return -1;
     }
@@ -812,7 +812,7 @@
         if (listen(s, LISTEN_BACKLOG) == SOCKET_ERROR) {
             *error = android::base::StringPrintf("cannot listen on socket: %s",
                     SystemErrorCodeToString(WSAGetLastError()).c_str());
-            D("could not listen on %s:%d: %s\n",
+            D("could not listen on %s:%d: %s",
               type != SOCK_STREAM ? "udp" : "tcp", port, error->c_str());
             return -1;
         }
@@ -821,7 +821,7 @@
     snprintf( f->name, sizeof(f->name), "%d(%s-server:%s%d)", fd,
               interface_address == INADDR_LOOPBACK ? "lo" : "any",
               type != SOCK_STREAM ? "udp:" : "", port );
-    D( "port %d type %s => fd %d\n", port, type != SOCK_STREAM ? "udp" : "tcp",
+    D( "port %d type %s => fd %d", port, type != SOCK_STREAM ? "udp" : "tcp",
        fd );
     f.release();
     return fd;
@@ -865,7 +865,7 @@
         *error = android::base::StringPrintf(
                 "cannot resolve host '%s' and port %s: %s", host.c_str(),
                 port_str, SystemErrorCodeToString(WSAGetLastError()).c_str());
-        D("%s\n", error->c_str());
+        D("%s", error->c_str());
         return -1;
     }
     std::unique_ptr<struct addrinfo, decltype(freeaddrinfo)*>
@@ -880,7 +880,7 @@
     if(s == INVALID_SOCKET) {
         *error = android::base::StringPrintf("cannot create socket: %s",
                 SystemErrorCodeToString(WSAGetLastError()).c_str());
-        D("%s\n", error->c_str());
+        D("%s", error->c_str());
         return -1;
     }
     f->fh_socket = s;
@@ -892,7 +892,7 @@
         *error = android::base::StringPrintf("cannot connect to %s:%s: %s",
                 host.c_str(), port_str,
                 SystemErrorCodeToString(WSAGetLastError()).c_str());
-        D("could not connect to %s:%s:%s: %s\n",
+        D("could not connect to %s:%s:%s: %s",
           type != SOCK_STREAM ? "udp" : "tcp", host.c_str(), port_str,
           error->c_str());
         return -1;
@@ -901,7 +901,7 @@
     const int fd = _fh_to_int(f.get());
     snprintf( f->name, sizeof(f->name), "%d(net-client:%s%d)", fd,
               type != SOCK_STREAM ? "udp:" : "", port );
-    D( "host '%s' port %d type %s => fd %d\n", host.c_str(), port,
+    D( "host '%s' port %d type %s => fd %d", host.c_str(), port,
        type != SOCK_STREAM ? "udp" : "tcp", fd );
     f.release();
     return fd;
@@ -913,7 +913,7 @@
     FH   serverfh = _fh_from_int(serverfd, __func__);
 
     if ( !serverfh || serverfh->clazz != &_fh_socket_class ) {
-        D("adb_socket_accept: invalid fd %d\n", serverfd);
+        D("adb_socket_accept: invalid fd %d", serverfd);
         errno = EBADF;
         return -1;
     }
@@ -936,7 +936,7 @@
 
     const int fd = _fh_to_int(fh.get());
     snprintf( fh->name, sizeof(fh->name), "%d(accept:%s)", fd, serverfh->name );
-    D( "adb_socket_accept on fd %d returns fd %d\n", serverfd, fd );
+    D( "adb_socket_accept on fd %d returns fd %d", serverfd, fd );
     fh.release();
     return  fd;
 }
@@ -947,7 +947,7 @@
     FH   fh = _fh_from_int(fd, __func__);
 
     if ( !fh || fh->clazz != &_fh_socket_class ) {
-        D("adb_setsockopt: invalid fd %d\n", fd);
+        D("adb_setsockopt: invalid fd %d", fd);
         errno = EBADF;
         return -1;
     }
@@ -970,15 +970,15 @@
     FH   f = _fh_from_int(fd, __func__);
 
     if (!f || f->clazz != &_fh_socket_class) {
-        D("adb_shutdown: invalid fd %d\n", fd);
+        D("adb_shutdown: invalid fd %d", fd);
         errno = EBADF;
         return -1;
     }
 
-    D( "adb_shutdown: %s\n", f->name);
+    D( "adb_shutdown: %s", f->name);
     if (shutdown(f->fh_socket, SD_BOTH) == SOCKET_ERROR) {
         const DWORD err = WSAGetLastError();
-        D("socket shutdown fd %d failed: %s\n", fd,
+        D("socket shutdown fd %d failed: %s", fd,
           SystemErrorCodeToString(err).c_str());
         _socket_set_errno(err);
         return -1;
@@ -1073,7 +1073,7 @@
 static void
 bip_buffer_init( BipBuffer  buffer )
 {
-    D( "bit_buffer_init %p\n", buffer );
+    D( "bit_buffer_init %p", buffer );
     buffer->a_start   = 0;
     buffer->a_end     = 0;
     buffer->b_end     = 0;
@@ -1103,7 +1103,7 @@
 static void
 bip_buffer_done( BipBuffer  bip )
 {
-    BIPD(( "bip_buffer_done: %d->%d\n", bip->fdin, bip->fdout ));
+    BIPD(( "bip_buffer_done: %d->%d", bip->fdin, bip->fdout ));
     CloseHandle( bip->evt_read );
     CloseHandle( bip->evt_write );
     DeleteCriticalSection( &bip->lock );
@@ -1117,7 +1117,7 @@
     if (len <= 0)
         return 0;
 
-    BIPD(( "bip_buffer_write: enter %d->%d len %d\n", bip->fdin, bip->fdout, len ));
+    BIPD(( "bip_buffer_write: enter %d->%d len %d", bip->fdin, bip->fdout, len ));
     BIPDUMP( src, len );
 
     EnterCriticalSection( &bip->lock );
@@ -1133,7 +1133,7 @@
         /* spinlocking here is probably unfair, but let's live with it */
         ret = WaitForSingleObject( bip->evt_write, INFINITE );
         if (ret != WAIT_OBJECT_0) {  /* buffer probably closed */
-            D( "bip_buffer_write: error %d->%d WaitForSingleObject returned %d, error %ld\n", bip->fdin, bip->fdout, ret, GetLastError() );
+            D( "bip_buffer_write: error %d->%d WaitForSingleObject returned %d, error %ld", bip->fdin, bip->fdout, ret, GetLastError() );
             return 0;
         }
         if (bip->closed) {
@@ -1143,7 +1143,7 @@
         EnterCriticalSection( &bip->lock );
     }
 
-    BIPD(( "bip_buffer_write: exec %d->%d len %d\n", bip->fdin, bip->fdout, len ));
+    BIPD(( "bip_buffer_write: exec %d->%d len %d", bip->fdin, bip->fdout, len ));
 
     avail = BIP_BUFFER_SIZE - bip->a_end;
     if (avail > 0)
@@ -1191,7 +1191,7 @@
         SetEvent( bip->evt_read );
     }
 
-    BIPD(( "bip_buffer_write: exit %d->%d count %d (as=%d ae=%d be=%d cw=%d cr=%d\n",
+    BIPD(( "bip_buffer_write: exit %d->%d count %d (as=%d ae=%d be=%d cw=%d cr=%d",
             bip->fdin, bip->fdout, count, bip->a_start, bip->a_end, bip->b_end, bip->can_write, bip->can_read ));
     LeaveCriticalSection( &bip->lock );
 
@@ -1206,7 +1206,7 @@
     if (len <= 0)
         return 0;
 
-    BIPD(( "bip_buffer_read: enter %d->%d len %d\n", bip->fdin, bip->fdout, len ));
+    BIPD(( "bip_buffer_read: enter %d->%d len %d", bip->fdin, bip->fdout, len ));
 
     EnterCriticalSection( &bip->lock );
     while ( !bip->can_read )
@@ -1226,7 +1226,7 @@
 
         ret = WaitForSingleObject( bip->evt_read, INFINITE );
         if (ret != WAIT_OBJECT_0) { /* probably closed buffer */
-            D( "bip_buffer_read: error %d->%d WaitForSingleObject returned %d, error %ld\n", bip->fdin, bip->fdout, ret, GetLastError());
+            D( "bip_buffer_read: error %d->%d WaitForSingleObject returned %d, error %ld", bip->fdin, bip->fdout, ret, GetLastError());
             return 0;
         }
         if (bip->closed) {
@@ -1237,7 +1237,7 @@
 #endif
     }
 
-    BIPD(( "bip_buffer_read: exec %d->%d len %d\n", bip->fdin, bip->fdout, len ));
+    BIPD(( "bip_buffer_read: exec %d->%d len %d", bip->fdin, bip->fdout, len ));
 
     avail = bip->a_end - bip->a_start;
     assert( avail > 0 );  /* since can_read is TRUE */
@@ -1284,7 +1284,7 @@
     }
 
     BIPDUMP( (const unsigned char*)dst - count, count );
-    BIPD(( "bip_buffer_read: exit %d->%d count %d (as=%d ae=%d be=%d cw=%d cr=%d\n",
+    BIPD(( "bip_buffer_read: exit %d->%d count %d (as=%d ae=%d be=%d cw=%d cr=%d",
             bip->fdin, bip->fdout, count, bip->a_start, bip->a_end, bip->b_end, bip->can_write, bip->can_read ));
     LeaveCriticalSection( &bip->lock );
 
@@ -1397,7 +1397,7 @@
 
     pair = reinterpret_cast<SocketPair>(malloc(sizeof(*pair)));
     if (pair == NULL) {
-        D("adb_socketpair: not enough memory to allocate pipes\n" );
+        D("adb_socketpair: not enough memory to allocate pipes" );
         return -1;
     }
 
@@ -1419,7 +1419,7 @@
 
     snprintf( fa->name, sizeof(fa->name), "%d(pair:%d)", sv[0], sv[1] );
     snprintf( fb->name, sizeof(fb->name), "%d(pair:%d)", sv[1], sv[0] );
-    D( "adb_socketpair: returns (%d, %d)\n", sv[0], sv[1] );
+    D( "adb_socketpair: returns (%d, %d)", sv[0], sv[1] );
     fa.release();
     fb.release();
     return 0;
@@ -1575,7 +1575,7 @@
     EventHook   node;
 
     if (f == NULL)  /* invalid arg */ {
-        D("event_looper_hook: invalid fd=%d\n", fd);
+        D("event_looper_hook: invalid fd=%d", fd);
         return;
     }
 
@@ -1589,12 +1589,12 @@
 
     if ( (node->wanted & events) != events ) {
         /* this should update start/stop/check/peek */
-        D("event_looper_hook: call hook for %d (new=%x, old=%x)\n",
+        D("event_looper_hook: call hook for %d (new=%x, old=%x)",
            fd, node->wanted, events);
         f->clazz->_fh_hook( f, events & ~node->wanted, node );
         node->wanted |= events;
     } else {
-        D("event_looper_hook: ignoring events %x for %d wanted=%x)\n",
+        D("event_looper_hook: ignoring events %x for %d wanted=%x)",
            events, fd, node->wanted);
     }
 }
@@ -1609,7 +1609,7 @@
     if (node != NULL) {
         int  events2 = events & node->wanted;
         if ( events2 == 0 ) {
-            D( "event_looper_unhook: events %x not registered for fd %d\n", events, fd );
+            D( "event_looper_unhook: events %x not registered for fd %d", events, fd );
             return;
         }
         node->wanted &= ~events2;
@@ -1728,7 +1728,7 @@
     threads = (WaitForAllParam*)malloc((chunks + (remains ? 1 : 0)) *
                                         sizeof(WaitForAllParam));
     if (threads == NULL) {
-        D("Unable to allocate thread array for %d handles.\n", handles_count);
+        D("Unable to allocate thread array for %d handles.", handles_count);
         return (int)WAIT_FAILED;
     }
 
@@ -1736,7 +1736,7 @@
      * reset" event that will remain set once it was set. */
     main_event = CreateEvent(NULL, TRUE, FALSE, NULL);
     if (main_event == NULL) {
-        D("Unable to create main event. Error: %ld\n", GetLastError());
+        D("Unable to create main event. Error: %ld", GetLastError());
         free(threads);
         return (int)WAIT_FAILED;
     }
@@ -1769,7 +1769,7 @@
                                                        &threads[chunk], 0, NULL);
         if (threads[chunk].thread == NULL) {
             /* Unable to create a waiter thread. Collapse. */
-            D("Unable to create a waiting thread %d of %d. errno=%d\n",
+            D("Unable to create a waiting thread %d of %d. errno=%d",
               chunk, chunks, errno);
             chunks = chunk;
             SetEvent(main_event);
@@ -1829,11 +1829,11 @@
         int  removes = events0 & ~events;
         int  adds    = events  & ~events0;
         if (removes) {
-            D("fdevent_update: remove %x from %d\n", removes, fde->fd);
+            D("fdevent_update: remove %x from %d", removes, fde->fd);
             event_looper_unhook( looper, fde->fd, removes );
         }
         if (adds) {
-            D("fdevent_update: add %x to %d\n", adds, fde->fd);
+            D("fdevent_update: add %x to %d", adds, fde->fd);
             event_looper_hook  ( looper, fde->fd, adds );
         }
     }
@@ -1865,7 +1865,7 @@
         for (hook = looper->hooks; hook; hook = hook->next)
         {
             if (hook->start && !hook->start(hook)) {
-                D( "fdevent_process: error when starting a hook\n" );
+                D( "fdevent_process: error when starting a hook" );
                 return;
             }
             if (hook->h != INVALID_HANDLE_VALUE) {
@@ -1883,7 +1883,7 @@
         }
 
         if (looper->htab_count == 0) {
-            D( "fdevent_process: nothing to wait for !!\n" );
+            D( "fdevent_process: nothing to wait for !!" );
             return;
         }
 
@@ -1891,17 +1891,17 @@
         {
             int   wait_ret;
 
-            D( "adb_win32: waiting for %d events\n", looper->htab_count );
+            D( "adb_win32: waiting for %d events", looper->htab_count );
             if (looper->htab_count > MAXIMUM_WAIT_OBJECTS) {
-                D("handle count %d exceeds MAXIMUM_WAIT_OBJECTS.\n", looper->htab_count);
+                D("handle count %d exceeds MAXIMUM_WAIT_OBJECTS.", looper->htab_count);
                 wait_ret = _wait_for_all(looper->htab, looper->htab_count);
             } else {
                 wait_ret = WaitForMultipleObjects( looper->htab_count, looper->htab, FALSE, INFINITE );
             }
             if (wait_ret == (int)WAIT_FAILED) {
-                D( "adb_win32: wait failed, error %ld\n", GetLastError() );
+                D( "adb_win32: wait failed, error %ld", GetLastError() );
             } else {
-                D( "adb_win32: got one (index %d)\n", wait_ret );
+                D( "adb_win32: got one (index %d)", wait_ret );
 
                 /* according to Cygwin, some objects like consoles wake up on "inappropriate" events
                  * like mouse movements. we need to filter these with the "check" function
@@ -1913,7 +1913,7 @@
                         if ( looper->htab[wait_ret] == hook->h       &&
                          (!hook->check || hook->check(hook)) )
                         {
-                            D( "adb_win32: signaling %s for %x\n", hook->fh->name, hook->ready );
+                            D( "adb_win32: signaling %s for %x", hook->fh->name, hook->ready );
                             event_hook_signal( hook );
                             gotone = 1;
                             break;
@@ -2205,14 +2205,14 @@
 
     hook->h = fh->event;
     if (hook->h == INVALID_HANDLE_VALUE) {
-        D( "_event_socket_start: no event for %s\n", fh->name );
+        D( "_event_socket_start: no event for %s", fh->name );
         return 0;
     }
 
     if ( flags != fh->mask ) {
-        D( "_event_socket_start: hooking %s for %x (flags %ld)\n", hook->fh->name, hook->wanted, flags );
+        D( "_event_socket_start: hooking %s for %x (flags %ld)", hook->fh->name, hook->wanted, flags );
         if ( WSAEventSelect( fh->fh_socket, hook->h, flags ) ) {
-            D( "_event_socket_start: WSAEventSelect() for %s failed, error %d\n", hook->fh->name, WSAGetLastError() );
+            D( "_event_socket_start: WSAEventSelect() for %s failed, error %d", hook->fh->name, WSAGetLastError() );
             CloseHandle( hook->h );
             hook->h = INVALID_HANDLE_VALUE;
             exit(1);
@@ -2241,7 +2241,7 @@
             ResetEvent( hook->h );
         }
     }
-    D( "_event_socket_check %s returns %d\n", fh->name, result );
+    D( "_event_socket_check %s returns %d", fh->name, result );
     return  result;
 }
 
@@ -2305,10 +2305,10 @@
         hook->h = wbip->evt_write;
 
     else {
-        D("_event_socketpair_start: can't handle FDE_READ+FDE_WRITE\n" );
+        D("_event_socketpair_start: can't handle FDE_READ+FDE_WRITE" );
         return 0;
     }
-    D( "_event_socketpair_start: hook %s for %x wanted=%x\n",
+    D( "_event_socketpair_start: hook %s for %x wanted=%x",
        hook->fh->name, _fh_to_int(fh), hook->wanted);
     return 1;
 }
@@ -3118,7 +3118,7 @@
             //
             // Consume the input and 'continue' to cause us to get a new key
             // event.
-            D("_console_read: unknown virtual key code: %d, enhanced: %s\n",
+            D("_console_read: unknown virtual key code: %d, enhanced: %s",
                 vk, _is_enhanced_key(control_key_state) ? "true" : "false");
             key_event->wRepeatCount = 0;
             continue;
@@ -3192,7 +3192,7 @@
         if (!SetConsoleMode(in, _old_console_mode & ~(ENABLE_PROCESSED_INPUT |
             ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT))) {
             // This really should not fail.
-            D("stdin_raw_init: SetConsoleMode() failed: %s\n",
+            D("stdin_raw_init: SetConsoleMode() failed: %s",
               SystemErrorCodeToString(GetLastError()).c_str());
         }
 
@@ -3214,7 +3214,7 @@
 
             if (!SetConsoleMode(in, _old_console_mode)) {
                 // This really should not fail.
-                D("stdin_raw_restore: SetConsoleMode() failed: %s\n",
+                D("stdin_raw_restore: SetConsoleMode() failed: %s",
                   SystemErrorCodeToString(GetLastError()).c_str());
             }
         }
diff --git a/adb/transport.cpp b/adb/transport.cpp
index 5a962de..e97c479 100644
--- a/adb/transport.cpp
+++ b/adb/transport.cpp
@@ -94,7 +94,7 @@
             len -= r;
             p += r;
         } else {
-            D("%s: read_packet (fd=%d), error ret=%d: %s\n", name, fd, r, strerror(errno));
+            D("%s: read_packet (fd=%d), error ret=%d: %s", name, fd, r, strerror(errno));
             return -1;
         }
     }
@@ -124,7 +124,7 @@
             len -= r;
             p += r;
         } else {
-            D("%s: write_packet (fd=%d) error ret=%d: %s\n", name, fd, r, strerror(errno));
+            D("%s: write_packet (fd=%d) error ret=%d: %s", name, fd, r, strerror(errno));
             return -1;
         }
     }
@@ -134,11 +134,11 @@
 static void transport_socket_events(int fd, unsigned events, void *_t)
 {
     atransport *t = reinterpret_cast<atransport*>(_t);
-    D("transport_socket_events(fd=%d, events=%04x,...)\n", fd, events);
+    D("transport_socket_events(fd=%d, events=%04x,...)", fd, events);
     if(events & FDE_READ){
         apacket *p = 0;
         if(read_packet(fd, t->serial, &p)){
-            D("%s: failed to read packet from transport socket on fd %d\n", t->serial, fd);
+            D("%s: failed to read packet from transport socket on fd %d", t->serial, fd);
         } else {
             handle_packet(p, (atransport *) _t);
         }
@@ -164,7 +164,7 @@
     print_packet("send", p);
 
     if (t == NULL) {
-        D("Transport is null \n");
+        D("Transport is null");
         // Zap errno because print_packet() and other stuff have errno effect.
         errno = 0;
         fatal_errno("Transport is null");
@@ -195,7 +195,7 @@
 
     adb_thread_setname(android::base::StringPrintf("<-%s",
                                                    (t->serial != nullptr ? t->serial : "transport")));
-    D("%s: starting read_transport thread on fd %d, SYNC online (%d)\n",
+    D("%s: starting read_transport thread on fd %d, SYNC online (%d)",
        t->serial, t->fd, t->sync_token + 1);
     p = get_apacket();
     p->msg.command = A_SYNC;
@@ -204,30 +204,30 @@
     p->msg.magic = A_SYNC ^ 0xffffffff;
     if(write_packet(t->fd, t->serial, &p)) {
         put_apacket(p);
-        D("%s: failed to write SYNC packet\n", t->serial);
+        D("%s: failed to write SYNC packet", t->serial);
         goto oops;
     }
 
-    D("%s: data pump started\n", t->serial);
+    D("%s: data pump started", t->serial);
     for(;;) {
         p = get_apacket();
 
         if(t->read_from_remote(p, t) == 0){
-            D("%s: received remote packet, sending to transport\n",
+            D("%s: received remote packet, sending to transport",
               t->serial);
             if(write_packet(t->fd, t->serial, &p)){
                 put_apacket(p);
-                D("%s: failed to write apacket to transport\n", t->serial);
+                D("%s: failed to write apacket to transport", t->serial);
                 goto oops;
             }
         } else {
-            D("%s: remote read failed for transport\n", t->serial);
+            D("%s: remote read failed for transport", t->serial);
             put_apacket(p);
             break;
         }
     }
 
-    D("%s: SYNC offline for transport\n", t->serial);
+    D("%s: SYNC offline for transport", t->serial);
     p = get_apacket();
     p->msg.command = A_SYNC;
     p->msg.arg0 = 0;
@@ -235,11 +235,11 @@
     p->msg.magic = A_SYNC ^ 0xffffffff;
     if(write_packet(t->fd, t->serial, &p)) {
         put_apacket(p);
-        D("%s: failed to write SYNC apacket to transport\n", t->serial);
+        D("%s: failed to write SYNC apacket to transport", t->serial);
     }
 
 oops:
-    D("%s: read_transport thread is exiting\n", t->serial);
+    D("%s: read_transport thread is exiting", t->serial);
     kick_transport(t);
     transport_unref(t);
     return 0;
@@ -255,42 +255,42 @@
 
     adb_thread_setname(android::base::StringPrintf("->%s",
                                                    (t->serial != nullptr ? t->serial : "transport")));
-    D("%s: starting write_transport thread, reading from fd %d\n",
+    D("%s: starting write_transport thread, reading from fd %d",
        t->serial, t->fd);
 
     for(;;){
         if(read_packet(t->fd, t->serial, &p)) {
-            D("%s: failed to read apacket from transport on fd %d\n",
+            D("%s: failed to read apacket from transport on fd %d",
                t->serial, t->fd );
             break;
         }
         if(p->msg.command == A_SYNC){
             if(p->msg.arg0 == 0) {
-                D("%s: transport SYNC offline\n", t->serial);
+                D("%s: transport SYNC offline", t->serial);
                 put_apacket(p);
                 break;
             } else {
                 if(p->msg.arg1 == t->sync_token) {
-                    D("%s: transport SYNC online\n", t->serial);
+                    D("%s: transport SYNC online", t->serial);
                     active = 1;
                 } else {
-                    D("%s: transport ignoring SYNC %d != %d\n",
+                    D("%s: transport ignoring SYNC %d != %d",
                       t->serial, p->msg.arg1, t->sync_token);
                 }
             }
         } else {
             if(active) {
-                D("%s: transport got packet, sending to remote\n", t->serial);
+                D("%s: transport got packet, sending to remote", t->serial);
                 t->write_to_remote(p, t);
             } else {
-                D("%s: transport ignoring packet while offline\n", t->serial);
+                D("%s: transport ignoring packet while offline", t->serial);
             }
         }
 
         put_apacket(p);
     }
 
-    D("%s: write_transport thread is exiting, fd %d\n", t->serial, t->fd);
+    D("%s: write_transport thread is exiting, fd %d", t->serial, t->fd);
     kick_transport(t);
     transport_unref(t);
     return 0;
@@ -355,7 +355,7 @@
     device_tracker*  tracker = (device_tracker*) socket;
     asocket*         peer    = socket->peer;
 
-    D( "device tracker %p removed\n", tracker);
+    D( "device tracker %p removed", tracker);
     if (peer) {
         peer->peer = NULL;
         peer->close(peer);
@@ -402,7 +402,7 @@
     device_tracker* tracker = reinterpret_cast<device_tracker*>(calloc(1, sizeof(*tracker)));
     if (tracker == nullptr) fatal("cannot allocate device tracker");
 
-    D( "device tracker %p created\n", tracker);
+    D( "device tracker %p created", tracker);
 
     tracker->socket.enqueue = device_tracker_enqueue;
     tracker->socket.ready   = device_tracker_ready;
@@ -456,7 +456,7 @@
             len -= r;
             p   += r;
         } else {
-            D("transport_read_action: on fd %d: %s\n", fd, strerror(errno));
+            D("transport_read_action: on fd %d: %s", fd, strerror(errno));
             return -1;
         }
     }
@@ -476,7 +476,7 @@
             len -= r;
             p   += r;
         } else {
-            D("transport_write_action: on fd %d: %s\n", fd, strerror(errno));
+            D("transport_write_action: on fd %d: %s", fd, strerror(errno));
             return -1;
         }
     }
@@ -500,7 +500,7 @@
     t = m.transport;
 
     if (m.action == 0) {
-        D("transport: %s removing and free'ing %d\n", t->serial, t->transport_socket);
+        D("transport: %s removing and free'ing %d", t->serial, t->transport_socket);
 
             /* IMPORTANT: the remove closes one half of the
             ** socket pair.  The close closes the other half.
@@ -538,7 +538,7 @@
             fatal_errno("cannot open transport socketpair");
         }
 
-        D("transport: %s socketpair: (%d,%d) starting\n", t->serial, s[0], s[1]);
+        D("transport: %s socketpair: (%d,%d) starting", t->serial, s[0], s[1]);
 
         t->transport_socket = s[0];
         t->fd = s[1];
@@ -574,7 +574,7 @@
     if(adb_socketpair(s)){
         fatal_errno("cannot open transport registration socketpair");
     }
-    D("socketpair: (%d,%d)\n", s[0], s[1]);
+    D("socketpair: (%d,%d)", s[0], s[1]);
 
     transport_registration_send = s[0];
     transport_registration_recv = s[1];
@@ -593,7 +593,7 @@
     tmsg m;
     m.transport = transport;
     m.action = 1;
-    D("transport: %s registered\n", transport->serial);
+    D("transport: %s registered", transport->serial);
     if(transport_write_action(transport_registration_send, &m)) {
         fatal_errno("cannot write transport registration socket\n");
     }
@@ -604,7 +604,7 @@
     tmsg m;
     m.transport = transport;
     m.action = 0;
-    D("transport: %s removed\n", transport->serial);
+    D("transport: %s removed", transport->serial);
     if(transport_write_action(transport_registration_send, &m)) {
         fatal_errno("cannot write transport registration socket\n");
     }
@@ -617,12 +617,12 @@
     CHECK_GT(t->ref_count, 0u);
     t->ref_count--;
     if (t->ref_count == 0) {
-        D("transport: %s unref (kicking and closing)\n", t->serial);
+        D("transport: %s unref (kicking and closing)", t->serial);
         kick_transport_locked(t);
         t->close(t);
         remove_transport(t);
     } else {
-        D("transport: %s unref (count=%zu)\n", t->serial, t->ref_count);
+        D("transport: %s unref (count=%zu)", t->serial, t->ref_count);
     }
     adb_mutex_unlock(&transport_lock);
 }
@@ -889,7 +889,7 @@
         serial = buf;
     }
 
-    D("transport: %s init'ing for socket %d, on port %d\n", serial, s, port);
+    D("transport: %s init'ing for socket %d, on port %d", serial, s, port);
     if (init_socket_transport(t, s, port, local) < 0) {
         delete t;
         return -1;
@@ -957,7 +957,7 @@
                             const char* devpath, unsigned writeable) {
     atransport* t = new atransport();
 
-    D("transport: %p init'ing for usb_handle %p (sn='%s')\n", t, usb,
+    D("transport: %p init'ing for usb_handle %p (sn='%s')", t, usb,
       serial ? serial : "");
     init_usb_transport(t, usb, (writeable ? kCsOffline : kCsNoPerm));
     if(serial) {
@@ -990,12 +990,12 @@
 int check_header(apacket *p, atransport *t)
 {
     if(p->msg.magic != (p->msg.command ^ 0xffffffff)) {
-        D("check_header(): invalid magic\n");
+        D("check_header(): invalid magic");
         return -1;
     }
 
     if(p->msg.data_length > t->get_max_payload()) {
-        D("check_header(): %u > atransport::max_payload = %zu\n",
+        D("check_header(): %u > atransport::max_payload = %zu",
             p->msg.data_length, t->get_max_payload());
         return -1;
     }
diff --git a/adb/transport_local.cpp b/adb/transport_local.cpp
index 6821cfc..0c4315a 100644
--- a/adb/transport_local.cpp
+++ b/adb/transport_local.cpp
@@ -51,22 +51,22 @@
 static int remote_read(apacket *p, atransport *t)
 {
     if(!ReadFdExactly(t->sfd, &p->msg, sizeof(amessage))){
-        D("remote local: read terminated (message)\n");
+        D("remote local: read terminated (message)");
         return -1;
     }
 
     if(check_header(p, t)) {
-        D("bad header: terminated (data)\n");
+        D("bad header: terminated (data)");
         return -1;
     }
 
     if(!ReadFdExactly(t->sfd, p->data, p->msg.data_length)){
-        D("remote local: terminated (data)\n");
+        D("remote local: terminated (data)");
         return -1;
     }
 
     if(check_data(p)) {
-        D("bad data: terminated (data)\n");
+        D("bad data: terminated (data)");
         return -1;
     }
 
@@ -78,7 +78,7 @@
     int   length = p->msg.data_length;
 
     if(!WriteFdExactly(t->sfd, &p->msg, sizeof(amessage) + length)) {
-        D("remote local: write terminated\n");
+        D("remote local: write terminated");
         return -1;
     }
 
@@ -108,7 +108,7 @@
     }
 
     if (fd >= 0) {
-        D("client: connected on remote on fd %d\n", fd);
+        D("client: connected on remote on fd %d", fd);
         close_on_exec(fd);
         disable_tcp_nagle(fd);
         std::string serial = android::base::StringPrintf("emulator-%d", console_port);
@@ -124,7 +124,7 @@
 static void *client_socket_thread(void *x)
 {
     adb_thread_setname("client_socket_thread");
-    D("transport: client_socket_thread() starting\n");
+    D("transport: client_socket_thread() starting");
     while (true) {
         int port = DEFAULT_ADB_LOCAL_TRANSPORT_PORT;
         int count = ADB_LOCAL_TRANSPORT_MAX;
@@ -148,14 +148,14 @@
     int port = (int) (uintptr_t) arg;
 
     adb_thread_setname("server socket");
-    D("transport: server_socket_thread() starting\n");
+    D("transport: server_socket_thread() starting");
     serverfd = -1;
     for(;;) {
         if(serverfd == -1) {
             std::string error;
             serverfd = network_inaddr_any_server(port, SOCK_STREAM, &error);
             if(serverfd < 0) {
-                D("server: cannot bind socket yet: %s\n", error.c_str());
+                D("server: cannot bind socket yet: %s", error.c_str());
                 adb_sleep_ms(1000);
                 continue;
             }
@@ -163,16 +163,16 @@
         }
 
         alen = sizeof(addr);
-        D("server: trying to get new connection from %d\n", port);
+        D("server: trying to get new connection from %d", port);
         fd = adb_socket_accept(serverfd, &addr, &alen);
         if(fd >= 0) {
-            D("server: new connection on fd %d\n", fd);
+            D("server: new connection on fd %d", fd);
             close_on_exec(fd);
             disable_tcp_nagle(fd);
             register_socket_transport(fd, "host", port, 1);
         }
     }
-    D("transport: server_socket_thread() exiting\n");
+    D("transport: server_socket_thread() exiting");
     return 0;
 }
 
@@ -234,7 +234,7 @@
     char con_name[32];
 
     adb_thread_setname("qemu socket");
-    D("transport: qemu_socket_thread() starting\n");
+    D("transport: qemu_socket_thread() starting");
 
     /* adb QEMUD service connection request. */
     snprintf(con_name, sizeof(con_name), "qemud:adb:%d", port);
@@ -244,7 +244,7 @@
     if (fd < 0) {
         /* This could be an older version of the emulator, that doesn't
          * implement adb QEMUD service. Fall back to the old TCP way. */
-        D("adb service is not available. Falling back to TCP socket.\n");
+        D("adb service is not available. Falling back to TCP socket.");
         adb_thread_create(server_socket_thread, arg);
         return 0;
     }
@@ -261,7 +261,7 @@
              * or 'ko' on failure. */
             res = adb_read(fd, tmp, sizeof(tmp));
             if (res != 2 || memcmp(tmp, _ok_resp, 2)) {
-                D("Accepting ADB host connection has failed.\n");
+                D("Accepting ADB host connection has failed.");
                 adb_close(fd);
             } else {
                 /* Host is connected. Register the transport, and start the
@@ -273,15 +273,15 @@
             /* Prepare for accepting of the next ADB host connection. */
             fd = qemu_pipe_open(con_name);
             if (fd < 0) {
-                D("adb service become unavailable.\n");
+                D("adb service become unavailable.");
                 return 0;
             }
         } else {
-            D("Unable to send the '%s' request to ADB service.\n", _accept_req);
+            D("Unable to send the '%s' request to ADB service.", _accept_req);
             return 0;
         }
     }
-    D("transport: qemu_socket_thread() exiting\n");
+    D("transport: qemu_socket_thread() exiting");
     return 0;
 }
 #endif  // !ADB_HOST
@@ -309,7 +309,7 @@
     debug_name = "server";
 #endif // !ADB_HOST
 
-    D("transport: local %s init\n", debug_name);
+    D("transport: local %s init", debug_name);
     if (!adb_thread_create(func, (void *) (uintptr_t) port)) {
         fatal_errno("cannot create local socket %s thread", debug_name);
     }
@@ -410,12 +410,12 @@
                     find_emulator_transport_by_adb_port_locked(adb_port);
             int index = get_available_local_transport_index_locked();
             if (existing_transport != NULL) {
-                D("local transport for port %d already registered (%p)?\n",
+                D("local transport for port %d already registered (%p)?",
                 adb_port, existing_transport);
                 fail = -1;
             } else if (index < 0) {
                 // Too many emulators.
-                D("cannot register more emulators. Maximum is %d\n",
+                D("cannot register more emulators. Maximum is %d",
                         ADB_LOCAL_TRANSPORT_MAX);
                 fail = -1;
             } else {
diff --git a/adb/transport_usb.cpp b/adb/transport_usb.cpp
index 96ccdad..b520607 100644
--- a/adb/transport_usb.cpp
+++ b/adb/transport_usb.cpp
@@ -28,24 +28,24 @@
 static int remote_read(apacket *p, atransport *t)
 {
     if(usb_read(t->usb, &p->msg, sizeof(amessage))){
-        D("remote usb: read terminated (message)\n");
+        D("remote usb: read terminated (message)");
         return -1;
     }
 
     if(check_header(p, t)) {
-        D("remote usb: check_header failed\n");
+        D("remote usb: check_header failed");
         return -1;
     }
 
     if(p->msg.data_length) {
         if(usb_read(t->usb, p->data, p->msg.data_length)){
-            D("remote usb: terminated (data)\n");
+            D("remote usb: terminated (data)");
             return -1;
         }
     }
 
     if(check_data(p)) {
-        D("remote usb: check_data failed\n");
+        D("remote usb: check_data failed");
         return -1;
     }
 
@@ -57,12 +57,12 @@
     unsigned size = p->msg.data_length;
 
     if(usb_write(t->usb, &p->msg, sizeof(amessage))) {
-        D("remote usb: 1 - write terminated\n");
+        D("remote usb: 1 - write terminated");
         return -1;
     }
     if(p->msg.data_length == 0) return 0;
     if(usb_write(t->usb, &p->data, size)) {
-        D("remote usb: 2 - write terminated\n");
+        D("remote usb: 2 - write terminated");
         return -1;
     }
 
@@ -82,7 +82,7 @@
 
 void init_usb_transport(atransport *t, usb_handle *h, ConnectionState state)
 {
-    D("transport: usb\n");
+    D("transport: usb");
     t->close = remote_close;
     t->kick = remote_kick;
     t->read_from_remote = remote_read;
diff --git a/adb/usb_linux.cpp b/adb/usb_linux.cpp
index 65b8735..f2b9820 100644
--- a/adb/usb_linux.cpp
+++ b/adb/usb_linux.cpp
@@ -159,7 +159,7 @@
 
                 // should have device and configuration descriptors, and atleast two endpoints
             if (desclength < USB_DT_DEVICE_SIZE + USB_DT_CONFIG_SIZE) {
-                D("desclength %zu is too small\n", desclength);
+                D("desclength %zu is too small", desclength);
                 unix_close(fd);
                 continue;
             }
@@ -180,7 +180,7 @@
             config = (struct usb_config_descriptor *)bufptr;
             bufptr += USB_DT_CONFIG_SIZE;
             if (config->bLength != USB_DT_CONFIG_SIZE || config->bDescriptorType != USB_DT_CONFIG) {
-                D("usb_config_descriptor not found\n");
+                D("usb_config_descriptor not found");
                 unix_close(fd);
                 continue;
             }
@@ -195,7 +195,7 @@
                     bufptr += length;
 
                     if (length != USB_DT_INTERFACE_SIZE) {
-                        D("interface descriptor has wrong size\n");
+                        D("interface descriptor has wrong size");
                         break;
                     }
 
@@ -237,14 +237,14 @@
                             ep1->bDescriptorType != USB_DT_ENDPOINT ||
                             ep2->bLength != USB_DT_ENDPOINT_SIZE ||
                             ep2->bDescriptorType != USB_DT_ENDPOINT) {
-                            D("endpoints not found\n");
+                            D("endpoints not found");
                             break;
                         }
 
                             // both endpoints should be bulk
                         if (ep1->bmAttributes != USB_ENDPOINT_XFER_BULK ||
                             ep2->bmAttributes != USB_ENDPOINT_XFER_BULK) {
-                            D("bulk endpoints not found\n");
+                            D("bulk endpoints not found");
                             continue;
                         }
                             /* aproto 01 needs 0 termination */
@@ -295,7 +295,7 @@
 
 static int usb_bulk_write(usb_handle* h, const void* data, int len) {
     std::unique_lock<std::mutex> lock(h->mutex);
-    D("++ usb_bulk_write ++\n");
+    D("++ usb_bulk_write ++");
 
     usbdevfs_urb* urb = &h->urb_out;
     memset(urb, 0, sizeof(*urb));
@@ -334,7 +334,7 @@
 
 static int usb_bulk_read(usb_handle* h, void* data, int len) {
     std::unique_lock<std::mutex> lock(h->mutex);
-    D("++ usb_bulk_read ++\n");
+    D("++ usb_bulk_read ++");
 
     usbdevfs_urb* urb = &h->urb_in;
     memset(urb, 0, sizeof(*urb));
@@ -355,7 +355,7 @@
 
     h->urb_in_busy = true;
     while (true) {
-        D("[ reap urb - wait ]\n");
+        D("[ reap urb - wait ]");
         h->reaper_thread = pthread_self();
         int fd = h->fd;
         lock.unlock();
@@ -375,14 +375,14 @@
             if (saved_errno == EINTR) {
                 continue;
             }
-            D("[ reap urb - error ]\n");
+            D("[ reap urb - error ]");
             errno = saved_errno;
             return -1;
         }
-        D("[ urb @%p status = %d, actual = %d ]\n", out, out->status, out->actual_length);
+        D("[ urb @%p status = %d, actual = %d ]", out, out->status, out->actual_length);
 
         if (out == &h->urb_in) {
-            D("[ reap urb - IN complete ]\n");
+            D("[ reap urb - IN complete ]");
             h->urb_in_busy = false;
             if (urb->status != 0) {
                 errno = -urb->status;
@@ -391,7 +391,7 @@
             return urb->actual_length;
         }
         if (out == &h->urb_out) {
-            D("[ reap urb - OUT compelete ]\n");
+            D("[ reap urb - OUT compelete ]");
             h->urb_out_busy = false;
             h->cv.notify_all();
         }
@@ -401,12 +401,12 @@
 
 int usb_write(usb_handle *h, const void *_data, int len)
 {
-    D("++ usb_write ++\n");
+    D("++ usb_write ++");
 
     unsigned char *data = (unsigned char*) _data;
     int n = usb_bulk_write(h, data, len);
     if (n != len) {
-        D("ERROR: n = %d, errno = %d (%s)\n", n, errno, strerror(errno));
+        D("ERROR: n = %d, errno = %d (%s)", n, errno, strerror(errno));
         return -1;
     }
 
@@ -416,7 +416,7 @@
         return usb_bulk_write(h, _data, 0);
     }
 
-    D("-- usb_write --\n");
+    D("-- usb_write --");
     return 0;
 }
 
@@ -425,23 +425,23 @@
     unsigned char *data = (unsigned char*) _data;
     int n;
 
-    D("++ usb_read ++\n");
+    D("++ usb_read ++");
     while(len > 0) {
         int xfer = len;
 
-        D("[ usb read %d fd = %d], path=%s\n", xfer, h->fd, h->path.c_str());
+        D("[ usb read %d fd = %d], path=%s", xfer, h->fd, h->path.c_str());
         n = usb_bulk_read(h, data, xfer);
-        D("[ usb read %d ] = %d, path=%s\n", xfer, n, h->path.c_str());
+        D("[ usb read %d ] = %d, path=%s", xfer, n, h->path.c_str());
         if(n != xfer) {
             if((errno == ETIMEDOUT) && (h->fd != -1)) {
-                D("[ timeout ]\n");
+                D("[ timeout ]");
                 if(n > 0){
                     data += n;
                     len -= n;
                 }
                 continue;
             }
-            D("ERROR: n = %d, errno = %d (%s)\n",
+            D("ERROR: n = %d, errno = %d (%s)",
                 n, errno, strerror(errno));
             return -1;
         }
@@ -450,13 +450,13 @@
         data += xfer;
     }
 
-    D("-- usb_read --\n");
+    D("-- usb_read --");
     return 0;
 }
 
 void usb_kick(usb_handle* h) {
     std::lock_guard<std::mutex> lock(h->mutex);
-    D("[ kicking %p (fd = %d) ]\n", h, h->fd);
+    D("[ kicking %p (fd = %d) ]", h, h->fd);
     if (!h->dead) {
         h->dead = true;
 
@@ -491,7 +491,7 @@
     std::lock_guard<std::mutex> lock(g_usb_handles_mutex);
     g_usb_handles.remove(h);
 
-    D("-- usb close %p (fd = %d) --\n", h, h->fd);
+    D("-- usb close %p (fd = %d) --", h, h->fd);
 
     delete h;
 
@@ -518,7 +518,7 @@
         }
     }
 
-    D("[ usb located new device %s (%d/%d/%d) ]\n", dev_name, ep_in, ep_out, interface);
+    D("[ usb located new device %s (%d/%d/%d) ]", dev_name, ep_in, ep_out, interface);
     std::unique_ptr<usb_handle> usb(new usb_handle);
     usb->path = dev_name;
     usb->ep_in = ep_in;
@@ -533,18 +533,18 @@
         // Opening RW failed, so see if we have RO access.
         usb->fd = unix_open(usb->path.c_str(), O_RDONLY | O_CLOEXEC);
         if (usb->fd == -1) {
-            D("[ usb open %s failed: %s]\n", usb->path.c_str(), strerror(errno));
+            D("[ usb open %s failed: %s]", usb->path.c_str(), strerror(errno));
             return;
         }
         usb->writeable = 0;
     }
 
-    D("[ usb opened %s%s, fd=%d]\n",
+    D("[ usb opened %s%s, fd=%d]",
       usb->path.c_str(), (usb->writeable ? "" : " (read-only)"), usb->fd);
 
     if (usb->writeable) {
         if (ioctl(usb->fd, USBDEVFS_CLAIMINTERFACE, &interface) != 0) {
-            D("[ usb ioctl(%d, USBDEVFS_CLAIMINTERFACE) failed: %s]\n", usb->fd, strerror(errno));
+            D("[ usb ioctl(%d, USBDEVFS_CLAIMINTERFACE) failed: %s]", usb->fd, strerror(errno));
             return;
         }
     }
@@ -554,7 +554,7 @@
         "/sys/bus/usb/devices/%s/serial", dev_path + 4);
     std::string serial;
     if (!android::base::ReadFileToString(serial_path, &serial)) {
-        D("[ usb read %s failed: %s ]\n", serial_path.c_str(), strerror(errno));
+        D("[ usb read %s failed: %s ]", serial_path.c_str(), strerror(errno));
         // We don't actually want to treat an unknown serial as an error because
         // devices aren't able to communicate a serial number in early bringup.
         // http://b/20883914
@@ -573,7 +573,7 @@
 
 static void* device_poll_thread(void* unused) {
     adb_thread_setname("device poll");
-    D("Created device thread\n");
+    D("Created device thread");
     while (true) {
         // TODO: Use inotify.
         find_usb_device("/dev/bus/usb", register_device);
diff --git a/adb/usb_linux_client.cpp b/adb/usb_linux_client.cpp
index e1d7594..c7a9b58 100644
--- a/adb/usb_linux_client.cpp
+++ b/adb/usb_linux_client.cpp
@@ -218,7 +218,7 @@
             adb_cond_wait(&usb->notify, &usb->lock);
         adb_mutex_unlock(&usb->lock);
 
-        D("[ usb_thread - opening device ]\n");
+        D("[ usb_thread - opening device ]");
         do {
             /* XXX use inotify? */
             fd = unix_open("/dev/android_adb", O_RDWR);
@@ -230,12 +230,12 @@
                 adb_sleep_ms(1000);
             }
         } while (fd < 0);
-        D("[ opening device succeeded ]\n");
+        D("[ opening device succeeded ]");
 
         close_on_exec(fd);
         usb->fd = fd;
 
-        D("[ usb_thread - registering device ]\n");
+        D("[ usb_thread - registering device ]");
         register_usb_transport(usb, 0, 0, 1);
     }
 
@@ -247,20 +247,20 @@
 {
     int n;
 
-    D("about to write (fd=%d, len=%d)\n", h->fd, len);
+    D("about to write (fd=%d, len=%d)", h->fd, len);
     n = unix_write(h->fd, data, len);
     if(n != len) {
-        D("ERROR: fd = %d, n = %d, errno = %d (%s)\n",
+        D("ERROR: fd = %d, n = %d, errno = %d (%s)",
             h->fd, n, errno, strerror(errno));
         return -1;
     }
-    D("[ done fd=%d ]\n", h->fd);
+    D("[ done fd=%d ]", h->fd);
     return 0;
 }
 
 static int usb_adb_read(usb_handle *h, void *data, int len)
 {
-    D("about to read (fd=%d, len=%d)\n", h->fd, len);
+    D("about to read (fd=%d, len=%d)", h->fd, len);
     while (len > 0) {
         // The kernel implementation of adb_read in f_adb.c doesn't support
         // reads larger then 4096 bytes. Read the data in 4096 byte chunks to
@@ -268,20 +268,20 @@
         int bytes_to_read = len < 4096 ? len : 4096;
         int n = unix_read(h->fd, data, bytes_to_read);
         if (n != bytes_to_read) {
-            D("ERROR: fd = %d, n = %d, errno = %d (%s)\n",
+            D("ERROR: fd = %d, n = %d, errno = %d (%s)",
                 h->fd, n, errno, strerror(errno));
             return -1;
         }
         len -= n;
         data = ((char*)data) + n;
     }
-    D("[ done fd=%d ]\n", h->fd);
+    D("[ done fd=%d ]", h->fd);
     return 0;
 }
 
 static void usb_adb_kick(usb_handle *h)
 {
-    D("usb_kick\n");
+    D("usb_kick");
     adb_mutex_lock(&h->lock);
     unix_close(h->fd);
     h->fd = -1;
@@ -311,12 +311,12 @@
     // and when we are not.
     int fd = unix_open("/dev/android_adb_enable", O_RDWR);
     if (fd < 0) {
-       D("failed to open /dev/android_adb_enable\n");
+       D("failed to open /dev/android_adb_enable");
     } else {
         close_on_exec(fd);
     }
 
-    D("[ usb_init - starting thread ]\n");
+    D("[ usb_init - starting thread ]");
     if (!adb_thread_create(usb_adb_open_thread, h)) {
         fatal_errno("cannot create usb thread");
     }
@@ -341,10 +341,10 @@
     v2_descriptor.ss_descs = ss_descriptors;
 
     if (h->control < 0) { // might have already done this before
-        D("OPENING %s\n", USB_FFS_ADB_EP0);
+        D("OPENING %s", USB_FFS_ADB_EP0);
         h->control = adb_open(USB_FFS_ADB_EP0, O_RDWR);
         if (h->control < 0) {
-            D("[ %s: cannot open control endpoint: errno=%d]\n", USB_FFS_ADB_EP0, errno);
+            D("[ %s: cannot open control endpoint: errno=%d]", USB_FFS_ADB_EP0, errno);
             goto err;
         }
 
@@ -356,30 +356,30 @@
             v1_descriptor.header.hs_count = 3;
             v1_descriptor.fs_descs = fs_descriptors;
             v1_descriptor.hs_descs = hs_descriptors;
-            D("[ %s: Switching to V1_descriptor format errno=%d ]\n", USB_FFS_ADB_EP0, errno);
+            D("[ %s: Switching to V1_descriptor format errno=%d ]", USB_FFS_ADB_EP0, errno);
             ret = adb_write(h->control, &v1_descriptor, sizeof(v1_descriptor));
             if (ret < 0) {
-                D("[ %s: write descriptors failed: errno=%d ]\n", USB_FFS_ADB_EP0, errno);
+                D("[ %s: write descriptors failed: errno=%d ]", USB_FFS_ADB_EP0, errno);
                 goto err;
             }
         }
 
         ret = adb_write(h->control, &strings, sizeof(strings));
         if (ret < 0) {
-            D("[ %s: writing strings failed: errno=%d]\n", USB_FFS_ADB_EP0, errno);
+            D("[ %s: writing strings failed: errno=%d]", USB_FFS_ADB_EP0, errno);
             goto err;
         }
     }
 
     h->bulk_out = adb_open(USB_FFS_ADB_OUT, O_RDWR);
     if (h->bulk_out < 0) {
-        D("[ %s: cannot open bulk-out ep: errno=%d ]\n", USB_FFS_ADB_OUT, errno);
+        D("[ %s: cannot open bulk-out ep: errno=%d ]", USB_FFS_ADB_OUT, errno);
         goto err;
     }
 
     h->bulk_in = adb_open(USB_FFS_ADB_IN, O_RDWR);
     if (h->bulk_in < 0) {
-        D("[ %s: cannot open bulk-in ep: errno=%d ]\n", USB_FFS_ADB_IN, errno);
+        D("[ %s: cannot open bulk-in ep: errno=%d ]", USB_FFS_ADB_IN, errno);
         goto err;
     }
 
@@ -424,7 +424,7 @@
         }
         property_set("sys.usb.ffs.ready", "1");
 
-        D("[ usb_thread - registering device ]\n");
+        D("[ usb_thread - registering device ]");
         register_usb_transport(usb, 0, 0, 1);
     }
 
@@ -442,19 +442,19 @@
         count += ret;
     }
 
-    D("[ bulk_write done fd=%d ]\n", bulk_in);
+    D("[ bulk_write done fd=%d ]", bulk_in);
     return count;
 }
 
 static int usb_ffs_write(usb_handle* h, const void* data, int len)
 {
-    D("about to write (fd=%d, len=%d)\n", h->bulk_in, len);
+    D("about to write (fd=%d, len=%d)", h->bulk_in, len);
     int n = bulk_write(h->bulk_in, reinterpret_cast<const uint8_t*>(data), len);
     if (n != len) {
-        D("ERROR: fd = %d, n = %d: %s\n", h->bulk_in, n, strerror(errno));
+        D("ERROR: fd = %d, n = %d: %s", h->bulk_in, n, strerror(errno));
         return -1;
     }
-    D("[ done fd=%d ]\n", h->bulk_in);
+    D("[ done fd=%d ]", h->bulk_in);
     return 0;
 }
 
@@ -465,7 +465,7 @@
     while (count < length) {
         int ret = adb_read(bulk_out, buf + count, length - count);
         if (ret < 0) {
-            D("[ bulk_read failed fd=%d length=%zu count=%zu ]\n", bulk_out, length, count);
+            D("[ bulk_read failed fd=%d length=%zu count=%zu ]", bulk_out, length, count);
             return -1;
         }
         count += ret;
@@ -476,13 +476,13 @@
 
 static int usb_ffs_read(usb_handle* h, void* data, int len)
 {
-    D("about to read (fd=%d, len=%d)\n", h->bulk_out, len);
+    D("about to read (fd=%d, len=%d)", h->bulk_out, len);
     int n = bulk_read(h->bulk_out, reinterpret_cast<uint8_t*>(data), len);
     if (n != len) {
-        D("ERROR: fd = %d, n = %d: %s\n", h->bulk_out, n, strerror(errno));
+        D("ERROR: fd = %d, n = %d: %s", h->bulk_out, n, strerror(errno));
         return -1;
     }
-    D("[ done fd=%d ]\n", h->bulk_out);
+    D("[ done fd=%d ]", h->bulk_out);
     return 0;
 }
 
@@ -492,11 +492,11 @@
 
     err = ioctl(h->bulk_in, FUNCTIONFS_CLEAR_HALT);
     if (err < 0)
-        D("[ kick: source (fd=%d) clear halt failed (%d) ]\n", h->bulk_in, errno);
+        D("[ kick: source (fd=%d) clear halt failed (%d) ]", h->bulk_in, errno);
 
     err = ioctl(h->bulk_out, FUNCTIONFS_CLEAR_HALT);
     if (err < 0)
-        D("[ kick: sink (fd=%d) clear halt failed (%d) ]\n", h->bulk_out, errno);
+        D("[ kick: sink (fd=%d) clear halt failed (%d) ]", h->bulk_out, errno);
 
     adb_mutex_lock(&h->lock);
 
@@ -514,7 +514,7 @@
 
 static void usb_ffs_init()
 {
-    D("[ usb_init - using FunctionFS ]\n");
+    D("[ usb_init - using FunctionFS ]");
 
     usb_handle* h = reinterpret_cast<usb_handle*>(calloc(1, sizeof(usb_handle)));
     if (h == nullptr) fatal("couldn't allocate usb_handle");
@@ -529,7 +529,7 @@
     adb_cond_init(&h->notify, 0);
     adb_mutex_init(&h->lock, 0);
 
-    D("[ usb_init - starting thread ]\n");
+    D("[ usb_init - starting thread ]");
     if (!adb_thread_create(usb_ffs_open_thread, h)) {
         fatal_errno("[ cannot create usb thread ]\n");
     }
diff --git a/adb/usb_windows.cpp b/adb/usb_windows.cpp
index ab36475..5bb0100 100644
--- a/adb/usb_windows.cpp
+++ b/adb/usb_windows.cpp
@@ -172,7 +172,7 @@
 
 void* device_poll_thread(void* unused) {
   adb_thread_setname("Device Poll");
-  D("Created device thread\n");
+  D("Created device thread");
 
   while(1) {
     find_devices();
@@ -208,7 +208,7 @@
   // heavyweight WMI APIs to get power notifications. But for the common case
   // of a developer's interactive session, a window message pump is more
   // appropriate.
-  D("Created power notification thread\n");
+  D("Created power notification thread");
   adb_thread_setname("Power Notifier");
 
   // Window class names are process specific.
@@ -252,7 +252,7 @@
   // do that, but it might be possible for that to occur when logging off or
   // shutting down. Not a big deal since the whole process will be going away
   // soon anyway.
-  D("Power notification thread exiting\n");
+  D("Power notification thread exiting");
 
   return NULL;
 }
@@ -272,7 +272,7 @@
   // Allocate our handle
   usb_handle* ret = (usb_handle*)calloc(1, sizeof(usb_handle));
   if (NULL == ret) {
-    D("Could not allocate %u bytes for usb_handle: %s\n", sizeof(usb_handle),
+    D("Could not allocate %u bytes for usb_handle: %s", sizeof(usb_handle),
       strerror(errno));
     goto fail;
   }
@@ -284,7 +284,7 @@
   // Create interface.
   ret->adb_interface = AdbCreateInterfaceByName(interface_name);
   if (NULL == ret->adb_interface) {
-    D("AdbCreateInterfaceByName failed: %s\n",
+    D("AdbCreateInterfaceByName failed: %s",
       SystemErrorCodeToString(GetLastError()).c_str());
     goto fail;
   }
@@ -295,7 +295,7 @@
                                    AdbOpenAccessTypeReadWrite,
                                    AdbOpenSharingModeReadWrite);
   if (NULL == ret->adb_read_pipe) {
-    D("AdbOpenDefaultBulkReadEndpoint failed: %s\n",
+    D("AdbOpenDefaultBulkReadEndpoint failed: %s",
       SystemErrorCodeToString(GetLastError()).c_str());
     goto fail;
   }
@@ -306,7 +306,7 @@
                                     AdbOpenAccessTypeReadWrite,
                                     AdbOpenSharingModeReadWrite);
   if (NULL == ret->adb_write_pipe) {
-    D("AdbOpenDefaultBulkWriteEndpoint failed: %s\n",
+    D("AdbOpenDefaultBulkWriteEndpoint failed: %s",
       SystemErrorCodeToString(GetLastError()).c_str());
     goto fail;
   }
@@ -318,14 +318,14 @@
                       &name_len,
                       true);
   if (0 == name_len) {
-    D("AdbGetInterfaceName returned name length of zero: %s\n",
+    D("AdbGetInterfaceName returned name length of zero: %s",
       SystemErrorCodeToString(GetLastError()).c_str());
     goto fail;
   }
 
   ret->interface_name = (char*)malloc(name_len);
   if (NULL == ret->interface_name) {
-    D("Could not allocate %lu bytes for interface_name: %s\n", name_len,
+    D("Could not allocate %lu bytes for interface_name: %s", name_len,
       strerror(errno));
     goto fail;
   }
@@ -335,7 +335,7 @@
                            ret->interface_name,
                            &name_len,
                            true)) {
-    D("AdbGetInterfaceName failed: %s\n",
+    D("AdbGetInterfaceName failed: %s",
       SystemErrorCodeToString(GetLastError()).c_str());
     goto fail;
   }
@@ -357,9 +357,9 @@
   unsigned long written = 0;
   int err = 0;
 
-  D("usb_write %d\n", len);
+  D("usb_write %d", len);
   if (NULL == handle) {
-    D("usb_write was passed NULL handle\n");
+    D("usb_write was passed NULL handle");
     err = EINVAL;
     goto fail;
   }
@@ -370,18 +370,18 @@
                             (unsigned long)len,
                             &written,
                             time_out)) {
-    D("AdbWriteEndpointSync failed: %s\n",
+    D("AdbWriteEndpointSync failed: %s",
       SystemErrorCodeToString(GetLastError()).c_str());
     err = EIO;
     goto fail;
   }
 
   // Make sure that we've written what we were asked to write
-  D("usb_write got: %ld, expected: %d\n", written, len);
+  D("usb_write got: %ld, expected: %d", written, len);
   if (written != (unsigned long)len) {
     // If this occurs, this code should be changed to repeatedly call
     // AdbWriteEndpointSync() until all bytes are written.
-    D("AdbWriteEndpointSync was supposed to write %d, but only wrote %ld\n",
+    D("AdbWriteEndpointSync was supposed to write %d, but only wrote %ld",
       len, written);
     err = EIO;
     goto fail;
@@ -394,7 +394,7 @@
                               0,
                               &written,
                               time_out)) {
-      D("AdbWriteEndpointSync of zero length packet failed: %s\n",
+      D("AdbWriteEndpointSync of zero length packet failed: %s",
         SystemErrorCodeToString(GetLastError()).c_str());
       err = EIO;
       goto fail;
@@ -407,11 +407,11 @@
   // Any failure should cause us to kick the device instead of leaving it a
   // zombie state with potential to hang.
   if (NULL != handle) {
-    D("Kicking device due to error in usb_write\n");
+    D("Kicking device due to error in usb_write");
     usb_kick(handle);
   }
 
-  D("usb_write failed\n");
+  D("usb_write failed");
   errno = err;
   return -1;
 }
@@ -421,9 +421,9 @@
   unsigned long read = 0;
   int err = 0;
 
-  D("usb_read %d\n", len);
+  D("usb_read %d", len);
   if (NULL == handle) {
-    D("usb_read was passed NULL handle\n");
+    D("usb_read was passed NULL handle");
     err = EINVAL;
     goto fail;
   }
@@ -431,12 +431,12 @@
   while (len > 0) {
     if (!AdbReadEndpointSync(handle->adb_read_pipe, data, len, &read,
                              time_out)) {
-      D("AdbReadEndpointSync failed: %s\n",
+      D("AdbReadEndpointSync failed: %s",
         SystemErrorCodeToString(GetLastError()).c_str());
       err = EIO;
       goto fail;
     }
-    D("usb_read got: %ld, expected: %d\n", read, len);
+    D("usb_read got: %ld, expected: %d", read, len);
 
     data = (char *)data + read;
     len -= read;
@@ -448,11 +448,11 @@
   // Any failure should cause us to kick the device instead of leaving it a
   // zombie state with potential to hang.
   if (NULL != handle) {
-    D("Kicking device due to error in usb_read\n");
+    D("Kicking device due to error in usb_read");
     usb_kick(handle);
   }
 
-  D("usb_read failed\n");
+  D("usb_read failed");
   errno = err;
   return -1;
 }
@@ -460,13 +460,13 @@
 // Wrapper around AdbCloseHandle() that logs diagnostics.
 static void _adb_close_handle(ADBAPIHANDLE adb_handle) {
   if (!AdbCloseHandle(adb_handle)) {
-    D("AdbCloseHandle(%p) failed: %s\n", adb_handle,
+    D("AdbCloseHandle(%p) failed: %s", adb_handle,
       SystemErrorCodeToString(GetLastError()).c_str());
   }
 }
 
 void usb_cleanup_handle(usb_handle* handle) {
-  D("usb_cleanup_handle\n");
+  D("usb_cleanup_handle");
   if (NULL != handle) {
     if (NULL != handle->interface_name)
       free(handle->interface_name);
@@ -494,7 +494,7 @@
 }
 
 void usb_kick(usb_handle* handle) {
-  D("usb_kick\n");
+  D("usb_kick");
   if (NULL != handle) {
     adb_mutex_lock(&usb_lock);
 
@@ -507,7 +507,7 @@
 }
 
 int usb_close(usb_handle* handle) {
-  D("usb_close\n");
+  D("usb_close");
 
   if (NULL != handle) {
     // Remove handle from the list
@@ -539,7 +539,7 @@
 
   if (!AdbGetUsbDeviceDescriptor(handle->adb_interface,
                                  &device_desc)) {
-    D("AdbGetUsbDeviceDescriptor failed: %s\n",
+    D("AdbGetUsbDeviceDescriptor failed: %s",
       SystemErrorCodeToString(GetLastError()).c_str());
     return 0;
   }
@@ -549,7 +549,7 @@
 
   if (!AdbGetUsbInterfaceDescriptor(handle->adb_interface,
                                     &interf_desc)) {
-    D("AdbGetUsbInterfaceDescriptor failed: %s\n",
+    D("AdbGetUsbInterfaceDescriptor failed: %s",
       SystemErrorCodeToString(GetLastError()).c_str());
     return 0;
   }
@@ -567,9 +567,9 @@
       // assuming zero is a valid bulk endpoint ID
       if (AdbGetEndpointInformation(handle->adb_interface, 0, &endpoint_info)) {
         handle->zero_mask = endpoint_info.max_packet_size - 1;
-        D("device zero_mask: 0x%x\n", handle->zero_mask);
+        D("device zero_mask: 0x%x", handle->zero_mask);
       } else {
-        D("AdbGetEndpointInformation failed: %s\n",
+        D("AdbGetEndpointInformation failed: %s",
           SystemErrorCodeToString(GetLastError()).c_str());
       }
     }
@@ -593,7 +593,7 @@
     AdbEnumInterfaces(usb_class_id, true, true, true);
 
   if (NULL == enum_handle) {
-    D("AdbEnumInterfaces failed: %s\n",
+    D("AdbEnumInterfaces failed: %s",
       SystemErrorCodeToString(GetLastError()).c_str());
     return;
   }
@@ -617,7 +617,7 @@
         if (NULL != handle) {
         // Lets see if this interface (device) belongs to us
         if (recognized_device(handle)) {
-          D("adding a new device %s\n", interf_name);
+          D("adding a new device %s", interf_name);
           char serial_number[512];
           unsigned long serial_number_len = sizeof(serial_number);
           if (AdbGetSerialNumber(handle->adb_interface,
@@ -628,12 +628,12 @@
             if (register_new_device(handle)) {
               register_usb_transport(handle, serial_number, NULL, 1);
             } else {
-              D("register_new_device failed for %s\n", interf_name);
+              D("register_new_device failed for %s", interf_name);
               usb_cleanup_handle(handle);
               free(handle);
             }
           } else {
-            D("cannot get serial number: %s\n",
+            D("cannot get serial number: %s",
               SystemErrorCodeToString(GetLastError()).c_str());
             usb_cleanup_handle(handle);
             free(handle);
@@ -650,7 +650,7 @@
 
   if (GetLastError() != ERROR_NO_MORE_ITEMS) {
     // Only ERROR_NO_MORE_ITEMS is expected at the end of enumeration.
-    D("AdbNextInterface failed: %s\n",
+    D("AdbNextInterface failed: %s",
       SystemErrorCodeToString(GetLastError()).c_str());
   }
 
diff --git a/include/private/android_filesystem_config.h b/include/private/android_filesystem_config.h
index 7047e0f..3e8d62a 100644
--- a/include/private/android_filesystem_config.h
+++ b/include/private/android_filesystem_config.h
@@ -32,6 +32,8 @@
 #include "android_filesystem_capability.h"
 #endif
 
+#define CAP_MASK_LONG(cap_name)  (1ULL << (cap_name))
+
 /* This is the master Users and Groups config for the platform.
  * DO NOT EVER RENUMBER
  */
diff --git a/libbacktrace/BacktraceCurrent.cpp b/libbacktrace/BacktraceCurrent.cpp
index 2714d93..d339550 100644
--- a/libbacktrace/BacktraceCurrent.cpp
+++ b/libbacktrace/BacktraceCurrent.cpp
@@ -93,6 +93,10 @@
 
 static pthread_mutex_t g_sigaction_mutex = PTHREAD_MUTEX_INITIALIZER;
 
+static void SignalLogOnly(int, siginfo_t*, void*) {
+  BACK_LOGE("pid %d, tid %d: Received a spurious signal %d\n", getpid(), gettid(), THREAD_SIGNAL);
+}
+
 static void SignalHandler(int, siginfo_t*, void* sigcontext) {
   ThreadEntry* entry = ThreadEntry::Get(getpid(), gettid(), false);
   if (!entry) {
@@ -151,9 +155,21 @@
   // that we are waiting for the first Wake() call made by the thread.
   bool wait_completed = entry->Wait(1);
 
+  if (!wait_completed && oldact.sa_sigaction == nullptr) {
+    // If the wait failed, it could be that the signal could not be delivered
+    // within the timeout. Add a signal handler that's simply going to log
+    // something so that we don't crash if the signal eventually gets
+    // delivered. Only do this if there isn't already an action set up.
+    memset(&act, 0, sizeof(act));
+    act.sa_sigaction = SignalLogOnly;
+    act.sa_flags = SA_RESTART | SA_SIGINFO | SA_ONSTACK;
+    sigemptyset(&act.sa_mask);
+    sigaction(THREAD_SIGNAL, &act, nullptr);
+  } else {
+    sigaction(THREAD_SIGNAL, &oldact, nullptr);
+  }
   // After the thread has received the signal, allow other unwinders to
   // continue.
-  sigaction(THREAD_SIGNAL, &oldact, nullptr);
   pthread_mutex_unlock(&g_sigaction_mutex);
 
   bool unwind_done = false;
diff --git a/libcutils/fs_config.c b/libcutils/fs_config.c
index 5f6f8f9..27981ff 100644
--- a/libcutils/fs_config.c
+++ b/libcutils/fs_config.c
@@ -135,8 +135,8 @@
     { 04770, AID_ROOT,      AID_RADIO,     0, "system/bin/pppd-ril" },
 
     /* the following files have enhanced capabilities and ARE included in user builds. */
-    { 00750, AID_ROOT,      AID_SHELL,     (1ULL << CAP_SETUID) | (1ULL << CAP_SETGID), "system/bin/run-as" },
-    { 00700, AID_SYSTEM,    AID_SHELL,     (1ULL << CAP_BLOCK_SUSPEND), "system/bin/inputflinger" },
+    { 00750, AID_ROOT,      AID_SHELL,     CAP_MASK_LONG(CAP_SETUID) | CAP_MASK_LONG(CAP_SETGID), "system/bin/run-as" },
+    { 00700, AID_SYSTEM,    AID_SHELL,     CAP_MASK_LONG(CAP_BLOCK_SUSPEND), "system/bin/inputflinger" },
 
     { 00750, AID_ROOT,      AID_ROOT,      0, "system/bin/uncrypt" },
     { 00750, AID_ROOT,      AID_ROOT,      0, "system/bin/install-recovery.sh" },
diff --git a/logd/LogBuffer.cpp b/logd/LogBuffer.cpp
index a93369e..0582a5f 100644
--- a/logd/LogBuffer.cpp
+++ b/logd/LogBuffer.cpp
@@ -238,7 +238,8 @@
     }
 }
 
-LogBufferElementCollection::iterator LogBuffer::erase(LogBufferElementCollection::iterator it) {
+LogBufferElementCollection::iterator LogBuffer::erase(
+        LogBufferElementCollection::iterator it, bool engageStats) {
     LogBufferElement *e = *it;
     log_id_t id = e->getLogId();
     LogBufferIteratorMap::iterator f = mLastWorstUid[id].find(e->getUid());
@@ -247,7 +248,11 @@
         mLastWorstUid[id].erase(f);
     }
     it = mLogElements.erase(it);
-    stats.subtract(e);
+    if (engageStats) {
+        stats.subtract(e);
+    } else {
+        stats.erase(e);
+    }
     delete e;
 
     return it;
@@ -442,9 +447,7 @@
 
             // merge any drops
             if (dropped && last.merge(e, dropped)) {
-                it = mLogElements.erase(it);
-                stats.erase(e);
-                delete e;
+                it = erase(it, false);
                 continue;
             }
 
@@ -510,9 +513,7 @@
                 stats.drop(e);
                 e->setDropped(1);
                 if (last.merge(e, 1)) {
-                    it = mLogElements.erase(it);
-                    stats.erase(e);
-                    delete e;
+                    it = erase(it, false);
                 } else {
                     last.add(e);
                     mLastWorstUid[id][e->getUid()] = it;
diff --git a/logd/LogBuffer.h b/logd/LogBuffer.h
index fcb05f5..de76693 100644
--- a/logd/LogBuffer.h
+++ b/logd/LogBuffer.h
@@ -87,7 +87,8 @@
 private:
     void maybePrune(log_id_t id);
     void prune(log_id_t id, unsigned long pruneRows, uid_t uid = AID_ROOT);
-    LogBufferElementCollection::iterator erase(LogBufferElementCollection::iterator it);
+    LogBufferElementCollection::iterator erase(
+        LogBufferElementCollection::iterator it, bool engageStats = true);
 };
 
 #endif // _LOGD_LOG_BUFFER_H__
diff --git a/metricsd/Android.mk b/metricsd/Android.mk
index 12dfa18..c5d5281 100644
--- a/metricsd/Android.mk
+++ b/metricsd/Android.mk
@@ -113,7 +113,6 @@
 LOCAL_EXPORT_C_INCLUDE_DIRS += \
     $(generated_sources_dir)/proto/system/core/metricsd
 LOCAL_SRC_FILES :=  $(call all-proto-files-under,uploader/proto)
-LOCAL_STATIC_LIBRARIES := libprotobuf-cpp-lite
 include $(BUILD_STATIC_LIBRARY)
 
 # metrics daemon.
diff --git a/metricsd/uploader/metrics_log_base.cc b/metricsd/uploader/metrics_log_base.cc
index ee325ae..311e43a 100644
--- a/metricsd/uploader/metrics_log_base.cc
+++ b/metricsd/uploader/metrics_log_base.cc
@@ -73,7 +73,7 @@
   // name.  We can then use this logging to find out what histogram name was
   // being hashed to a given MD5 value by just running the version of Chromium
   // in question with --enable-logging.
-  DVLOG(1) << "Metrics: Hash numeric [" << value << "]=[" << hash << "]";
+  VLOG(1) << "Metrics: Hash numeric [" << value << "]=[" << hash << "]";
 
   return hash;
 }
diff --git a/rootdir/init.rc b/rootdir/init.rc
index cf16f01..5f1169d 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -8,7 +8,6 @@
 import /init.usb.rc
 import /init.${ro.hardware}.rc
 import /init.${ro.zygote}.rc
-import /init.trace.rc
 
 on early-init
     # Set init and its forked children's oom_adj.
@@ -494,13 +493,3 @@
 service flash_recovery /system/bin/install-recovery.sh
     class main
     oneshot
-
-service uncrypt /system/bin/uncrypt
-    class main
-    disabled
-    oneshot
-
-service pre-recovery /system/bin/uncrypt --reboot
-    class main
-    disabled
-    oneshot
diff --git a/rootdir/init.trace.rc b/rootdir/init.trace.rc
deleted file mode 100644
index cde9c37..0000000
--- a/rootdir/init.trace.rc
+++ /dev/null
@@ -1,62 +0,0 @@
-## Permissions to allow system-wide tracing to the kernel trace buffer.
-##
-on boot
-
-# Allow writing to the kernel trace log.
-    chmod 0222 /sys/kernel/debug/tracing/trace_marker
-
-# Allow the shell group to enable (some) kernel tracing.
-    chown root shell /sys/kernel/debug/tracing/trace_clock
-    chown root shell /sys/kernel/debug/tracing/buffer_size_kb
-    chown root shell /sys/kernel/debug/tracing/options/overwrite
-    chown root shell /sys/kernel/debug/tracing/options/print-tgid
-    chown root shell /sys/kernel/debug/tracing/events/sched/sched_switch/enable
-    chown root shell /sys/kernel/debug/tracing/events/sched/sched_wakeup/enable
-    chown root shell /sys/kernel/debug/tracing/events/power/cpu_frequency/enable
-    chown root shell /sys/kernel/debug/tracing/events/power/cpu_idle/enable
-    chown root shell /sys/kernel/debug/tracing/events/power/clock_set_rate/enable
-    chown root shell /sys/kernel/debug/tracing/events/cpufreq_interactive/enable
-    chown root shell /sys/kernel/debug/tracing/events/vmscan/mm_vmscan_direct_reclaim_begin/enable
-    chown root shell /sys/kernel/debug/tracing/events/vmscan/mm_vmscan_direct_reclaim_end/enable
-    chown root shell /sys/kernel/debug/tracing/events/vmscan/mm_vmscan_kswapd_wake/enable
-    chown root shell /sys/kernel/debug/tracing/events/vmscan/mm_vmscan_kswapd_sleep/enable
-    chown root shell /sys/kernel/debug/tracing/events/binder/binder_transaction/enable
-    chown root shell /sys/kernel/debug/tracing/events/binder/binder_transaction_received/enable
-    chown root shell /sys/kernel/debug/tracing/events/binder/binder_lock/enable
-    chown root shell /sys/kernel/debug/tracing/events/binder/binder_locked/enable
-    chown root shell /sys/kernel/debug/tracing/events/binder/binder_unlock/enable
-
-    chown root shell /sys/kernel/debug/tracing/tracing_on
-
-    chmod 0664 /sys/kernel/debug/tracing/trace_clock
-    chmod 0664 /sys/kernel/debug/tracing/buffer_size_kb
-    chmod 0664 /sys/kernel/debug/tracing/options/overwrite
-    chmod 0664 /sys/kernel/debug/tracing/options/print-tgid
-    chmod 0664 /sys/kernel/debug/tracing/events/sched/sched_switch/enable
-    chmod 0664 /sys/kernel/debug/tracing/events/sched/sched_wakeup/enable
-    chmod 0664 /sys/kernel/debug/tracing/events/power/cpu_frequency/enable
-    chmod 0664 /sys/kernel/debug/tracing/events/power/cpu_idle/enable
-    chmod 0664 /sys/kernel/debug/tracing/events/power/clock_set_rate/enable
-    chmod 0664 /sys/kernel/debug/tracing/events/cpufreq_interactive/enable
-    chmod 0664 /sys/kernel/debug/tracing/events/vmscan/mm_vmscan_direct_reclaim_begin/enable
-    chmod 0664 /sys/kernel/debug/tracing/events/vmscan/mm_vmscan_direct_reclaim_end/enable
-    chmod 0664 /sys/kernel/debug/tracing/events/vmscan/mm_vmscan_kswapd_wake/enable
-    chmod 0664 /sys/kernel/debug/tracing/events/vmscan/mm_vmscan_kswapd_sleep/enable
-    chmod 0664 /sys/kernel/debug/tracing/tracing_on
-    chmod 0664 /sys/kernel/debug/tracing/events/binder/binder_transaction/enable
-    chmod 0664 /sys/kernel/debug/tracing/events/binder/binder_transaction_received/enable
-    chmod 0664 /sys/kernel/debug/tracing/events/binder/binder_lock/enable
-    chmod 0664 /sys/kernel/debug/tracing/events/binder/binder_locked/enable
-    chmod 0664 /sys/kernel/debug/tracing/events/binder/binder_unlock/enable
-
-# Allow only the shell group to read and truncate the kernel trace.
-    chown root shell /sys/kernel/debug/tracing/trace
-    chmod 0660 /sys/kernel/debug/tracing/trace
-
-on property:persist.debug.atrace.boottrace=1
-    start boottrace
-
-# Run atrace with the categories written in a file
-service boottrace /system/bin/atrace --async_start -f /data/misc/boottrace/categories
-    disabled
-    oneshot
diff --git a/rootdir/init.usb.rc b/rootdir/init.usb.rc
index e290ca4..4e6f2a8 100644
--- a/rootdir/init.usb.rc
+++ b/rootdir/init.usb.rc
@@ -8,6 +8,19 @@
     chmod 0660 /sys/class/android_usb/android0/f_mass_storage/lun/file
     chown system system /sys/class/android_usb/android0/f_rndis/ethaddr
     chmod 0660 /sys/class/android_usb/android0/f_rndis/ethaddr
+    mkdir /data/misc/adb 02750 system shell
+    mkdir /data/adb 0700 root root
+
+# adbd is controlled via property triggers in init.<platform>.usb.rc
+service adbd /sbin/adbd --root_seclabel=u:r:su:s0
+    class core
+    socket adbd stream 660 system system
+    disabled
+    seclabel u:r:adbd:s0
+
+# adbd on at boot in emulator
+on property:ro.kernel.qemu=1
+    start adbd
 
 # Used to disable USB when switching states
 on property:sys.usb.config=none
diff --git a/toolbox/Android.mk b/toolbox/Android.mk
index 24f702f..1d3605e 100644
--- a/toolbox/Android.mk
+++ b/toolbox/Android.mk
@@ -43,7 +43,6 @@
     iftop \
     ioctl \
     log \
-    ls \
     lsof \
     nandread \
     newfs_msdos \
diff --git a/toolbox/ls.c b/toolbox/ls.c
deleted file mode 100644
index 9a89dd4..0000000
--- a/toolbox/ls.c
+++ /dev/null
@@ -1,588 +0,0 @@
-#include <dirent.h>
-#include <errno.h>
-#include <grp.h>
-#include <limits.h>
-#include <pwd.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <sys/sysmacros.h>
-#include <sys/types.h>
-#include <time.h>
-#include <unistd.h>
-
-#include <selinux/selinux.h>
-
-// simple dynamic array of strings.
-typedef struct {
-    int count;
-    int capacity;
-    void** items;
-} strlist_t;
-
-#define STRLIST_INITIALIZER { 0, 0, NULL }
-
-/* Used to iterate over a strlist_t
- * _list   :: pointer to strlist_t object
- * _item   :: name of local variable name defined within the loop with
- *            type 'char*'
- * _stmnt  :: C statement executed in each iteration
- *
- * This macro is only intended for simple uses. Do not add or remove items
- * to/from the list during iteration.
- */
-#define  STRLIST_FOREACH(_list,_item,_stmnt) \
-    do { \
-        int _nn_##__LINE__ = 0; \
-        for (;_nn_##__LINE__ < (_list)->count; ++ _nn_##__LINE__) { \
-            char* _item = (char*)(_list)->items[_nn_##__LINE__]; \
-            _stmnt; \
-        } \
-    } while (0)
-
-static void dynarray_reserve_more( strlist_t *a, int count ) {
-    int old_cap = a->capacity;
-    int new_cap = old_cap;
-    const int max_cap = INT_MAX/sizeof(void*);
-    void** new_items;
-    int new_count = a->count + count;
-
-    if (count <= 0)
-        return;
-
-    if (count > max_cap - a->count)
-        abort();
-
-    new_count = a->count + count;
-
-    while (new_cap < new_count) {
-        old_cap = new_cap;
-        new_cap += (new_cap >> 2) + 4;
-        if (new_cap < old_cap || new_cap > max_cap) {
-            new_cap = max_cap;
-        }
-    }
-    new_items = realloc(a->items, new_cap*sizeof(void*));
-    if (new_items == NULL)
-        abort();
-
-    a->items = new_items;
-    a->capacity = new_cap;
-}
-
-void strlist_init( strlist_t *list ) {
-    list->count = list->capacity = 0;
-    list->items = NULL;
-}
-
-// append a new string made of the first 'slen' characters from 'str'
-// followed by a trailing zero.
-void strlist_append_b( strlist_t *list, const void* str, size_t  slen ) {
-    char *copy = malloc(slen+1);
-    memcpy(copy, str, slen);
-    copy[slen] = '\0';
-    if (list->count >= list->capacity)
-        dynarray_reserve_more(list, 1);
-    list->items[list->count++] = copy;
-}
-
-// append the copy of a given input string to a strlist_t.
-void strlist_append_dup( strlist_t *list, const char *str) {
-    strlist_append_b(list, str, strlen(str));
-}
-
-// note: strlist_done will free all the strings owned by the list.
-void strlist_done( strlist_t *list ) {
-    STRLIST_FOREACH(list, string, free(string));
-    free(list->items);
-    list->items = NULL;
-    list->count = list->capacity = 0;
-}
-
-static int strlist_compare_strings(const void* a, const void* b) {
-    const char *sa = *(const char **)a;
-    const char *sb = *(const char **)b;
-    return strcmp(sa, sb);
-}
-
-/* sort the strings in a given list (using strcmp) */
-void strlist_sort( strlist_t *list ) {
-    if (list->count > 0) {
-        qsort(list->items, (size_t)list->count, sizeof(void*), strlist_compare_strings);
-    }
-}
-
-
-// bits for flags argument
-#define LIST_LONG           (1 << 0)
-#define LIST_ALL            (1 << 1)
-#define LIST_RECURSIVE      (1 << 2)
-#define LIST_DIRECTORIES    (1 << 3)
-#define LIST_SIZE           (1 << 4)
-#define LIST_LONG_NUMERIC   (1 << 5)
-#define LIST_CLASSIFY       (1 << 6)
-#define LIST_MACLABEL       (1 << 7)
-#define LIST_INODE          (1 << 8)
-
-// fwd
-static int listpath(const char *name, int flags);
-
-static char mode2kind(mode_t mode)
-{
-    switch(mode & S_IFMT){
-    case S_IFSOCK: return 's';
-    case S_IFLNK: return 'l';
-    case S_IFREG: return '-';
-    case S_IFDIR: return 'd';
-    case S_IFBLK: return 'b';
-    case S_IFCHR: return 'c';
-    case S_IFIFO: return 'p';
-    default: return '?';
-    }
-}
-
-void strmode(mode_t mode, char *out)
-{
-    *out++ = mode2kind(mode);
-
-    *out++ = (mode & 0400) ? 'r' : '-';
-    *out++ = (mode & 0200) ? 'w' : '-';
-    if(mode & 04000) {
-        *out++ = (mode & 0100) ? 's' : 'S';
-    } else {
-        *out++ = (mode & 0100) ? 'x' : '-';
-    }
-    *out++ = (mode & 040) ? 'r' : '-';
-    *out++ = (mode & 020) ? 'w' : '-';
-    if(mode & 02000) {
-        *out++ = (mode & 010) ? 's' : 'S';
-    } else {
-        *out++ = (mode & 010) ? 'x' : '-';
-    }
-    *out++ = (mode & 04) ? 'r' : '-';
-    *out++ = (mode & 02) ? 'w' : '-';
-    if(mode & 01000) {
-        *out++ = (mode & 01) ? 't' : 'T';
-    } else {
-        *out++ = (mode & 01) ? 'x' : '-';
-    }
-    *out = 0;
-}
-
-static void user2str(uid_t uid, char *out, size_t out_size)
-{
-    struct passwd *pw = getpwuid(uid);
-    if(pw) {
-        strlcpy(out, pw->pw_name, out_size);
-    } else {
-        snprintf(out, out_size, "%d", uid);
-    }
-}
-
-static void group2str(gid_t gid, char *out, size_t out_size)
-{
-    struct group *gr = getgrgid(gid);
-    if(gr) {
-        strlcpy(out, gr->gr_name, out_size);
-    } else {
-        snprintf(out, out_size, "%d", gid);
-    }
-}
-
-static int show_total_size(const char *dirname, DIR *d, int flags)
-{
-    struct dirent *de;
-    char tmp[1024];
-    struct stat s;
-    int sum = 0;
-
-    /* run through the directory and sum up the file block sizes */
-    while ((de = readdir(d)) != 0) {
-        if (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0)
-            continue;
-        if (de->d_name[0] == '.' && (flags & LIST_ALL) == 0)
-            continue;
-
-        if (strcmp(dirname, "/") == 0)
-            snprintf(tmp, sizeof(tmp), "/%s", de->d_name);
-        else
-            snprintf(tmp, sizeof(tmp), "%s/%s", dirname, de->d_name);
-
-        if (lstat(tmp, &s) < 0) {
-            fprintf(stderr, "stat failed on %s: %s\n", tmp, strerror(errno));
-            rewinddir(d);
-            return -1;
-        }
-
-        sum += s.st_blocks / 2;
-    }
-
-    printf("total %d\n", sum);
-    rewinddir(d);
-    return 0;
-}
-
-static int listfile_size(const char *path, const char *filename, struct stat *s,
-                         int flags)
-{
-    if(!s || !path) {
-        return -1;
-    }
-
-    /* blocks are 512 bytes, we want output to be KB */
-    if ((flags & LIST_SIZE) != 0) {
-        printf("%lld ", (long long)s->st_blocks / 2);
-    }
-
-    if ((flags & LIST_CLASSIFY) != 0) {
-        char filetype = mode2kind(s->st_mode);
-        if (filetype != 'l') {
-            printf("%c ", filetype);
-        } else {
-            struct stat link_dest;
-            if (!stat(path, &link_dest)) {
-                printf("l%c ", mode2kind(link_dest.st_mode));
-            } else {
-                fprintf(stderr, "stat '%s' failed: %s\n", path, strerror(errno));
-                printf("l? ");
-            }
-        }
-    }
-
-    printf("%s\n", filename);
-
-    return 0;
-}
-
-static int listfile_long(const char *path, struct stat *s, int flags)
-{
-    char date[32];
-    char mode[16];
-    char user[32];
-    char group[32];
-    const char *name;
-
-    if(!s || !path) {
-        return -1;
-    }
-
-    /* name is anything after the final '/', or the whole path if none*/
-    name = strrchr(path, '/');
-    if(name == 0) {
-        name = path;
-    } else {
-        name++;
-    }
-
-    strmode(s->st_mode, mode);
-    if (flags & LIST_LONG_NUMERIC) {
-        snprintf(user, sizeof(user), "%u", s->st_uid);
-        snprintf(group, sizeof(group), "%u", s->st_gid);
-    } else {
-        user2str(s->st_uid, user, sizeof(user));
-        group2str(s->st_gid, group, sizeof(group));
-    }
-
-    strftime(date, 32, "%Y-%m-%d %H:%M", localtime((const time_t*)&s->st_mtime));
-    date[31] = 0;
-
-// 12345678901234567890123456789012345678901234567890123456789012345678901234567890
-// MMMMMMMM UUUUUUUU GGGGGGGGG XXXXXXXX YYYY-MM-DD HH:MM NAME (->LINK)
-
-    switch(s->st_mode & S_IFMT) {
-    case S_IFBLK:
-    case S_IFCHR:
-        printf("%s %-8s %-8s %3d, %3d %s %s\n",
-               mode, user, group,
-               major(s->st_rdev), minor(s->st_rdev),
-               date, name);
-        break;
-    case S_IFREG:
-        printf("%s %-8s %-8s %8lld %s %s\n",
-               mode, user, group, (long long)s->st_size, date, name);
-        break;
-    case S_IFLNK: {
-        char linkto[256];
-        ssize_t len;
-
-        len = readlink(path, linkto, 256);
-        if(len < 0) return -1;
-
-        if(len > 255) {
-            linkto[252] = '.';
-            linkto[253] = '.';
-            linkto[254] = '.';
-            linkto[255] = 0;
-        } else {
-            linkto[len] = 0;
-        }
-
-        printf("%s %-8s %-8s          %s %s -> %s\n",
-               mode, user, group, date, name, linkto);
-        break;
-    }
-    default:
-        printf("%s %-8s %-8s          %s %s\n",
-               mode, user, group, date, name);
-
-    }
-    return 0;
-}
-
-static int listfile_maclabel(const char *path, struct stat *s)
-{
-    char mode[16];
-    char user[32];
-    char group[32];
-    char *maclabel = NULL;
-    const char *name;
-
-    if(!s || !path) {
-        return -1;
-    }
-
-    /* name is anything after the final '/', or the whole path if none*/
-    name = strrchr(path, '/');
-    if(name == 0) {
-        name = path;
-    } else {
-        name++;
-    }
-
-    lgetfilecon(path, &maclabel);
-    if (!maclabel) {
-        return -1;
-    }
-
-    strmode(s->st_mode, mode);
-    user2str(s->st_uid, user, sizeof(user));
-    group2str(s->st_gid, group, sizeof(group));
-
-    switch(s->st_mode & S_IFMT) {
-    case S_IFLNK: {
-        char linkto[256];
-        ssize_t len;
-
-        len = readlink(path, linkto, sizeof(linkto));
-        if(len < 0) return -1;
-
-        if((size_t)len > sizeof(linkto)-1) {
-            linkto[sizeof(linkto)-4] = '.';
-            linkto[sizeof(linkto)-3] = '.';
-            linkto[sizeof(linkto)-2] = '.';
-            linkto[sizeof(linkto)-1] = 0;
-        } else {
-            linkto[len] = 0;
-        }
-
-        printf("%s %-8s %-8s          %s %s -> %s\n",
-               mode, user, group, maclabel, name, linkto);
-        break;
-    }
-    default:
-        printf("%s %-8s %-8s          %s %s\n",
-               mode, user, group, maclabel, name);
-
-    }
-
-    free(maclabel);
-
-    return 0;
-}
-
-static int listfile(const char *dirname, const char *filename, int flags)
-{
-    struct stat s;
-
-    if ((flags & (LIST_LONG | LIST_SIZE | LIST_CLASSIFY | LIST_MACLABEL | LIST_INODE)) == 0) {
-        printf("%s\n", filename);
-        return 0;
-    }
-
-    char tmp[4096];
-    const char* pathname = filename;
-
-    if (dirname != NULL) {
-        snprintf(tmp, sizeof(tmp), "%s/%s", dirname, filename);
-        pathname = tmp;
-    } else {
-        pathname = filename;
-    }
-
-    if(lstat(pathname, &s) < 0) {
-        fprintf(stderr, "lstat '%s' failed: %s\n", pathname, strerror(errno));
-        return -1;
-    }
-
-    if(flags & LIST_INODE) {
-        printf("%8llu ", (unsigned long long)s.st_ino);
-    }
-
-    if ((flags & LIST_MACLABEL) != 0) {
-        return listfile_maclabel(pathname, &s);
-    } else if ((flags & LIST_LONG) != 0) {
-        return listfile_long(pathname, &s, flags);
-    } else /*((flags & LIST_SIZE) != 0)*/ {
-        return listfile_size(pathname, filename, &s, flags);
-    }
-}
-
-static int listdir(const char *name, int flags)
-{
-    char tmp[4096];
-    DIR *d;
-    struct dirent *de;
-    strlist_t  files = STRLIST_INITIALIZER;
-
-    d = opendir(name);
-    if(d == 0) {
-        fprintf(stderr, "opendir failed, %s\n", strerror(errno));
-        return -1;
-    }
-
-    if ((flags & LIST_SIZE) != 0) {
-        show_total_size(name, d, flags);
-    }
-
-    while((de = readdir(d)) != 0){
-        if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, "..")) continue;
-        if(de->d_name[0] == '.' && (flags & LIST_ALL) == 0) continue;
-
-        strlist_append_dup(&files, de->d_name);
-    }
-
-    strlist_sort(&files);
-    STRLIST_FOREACH(&files, filename, listfile(name, filename, flags));
-    strlist_done(&files);
-
-    if (flags & LIST_RECURSIVE) {
-        strlist_t subdirs = STRLIST_INITIALIZER;
-
-        rewinddir(d);
-
-        while ((de = readdir(d)) != 0) {
-            struct stat s;
-            int err;
-
-            if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, ".."))
-                continue;
-            if (de->d_name[0] == '.' && (flags & LIST_ALL) == 0)
-                continue;
-
-            if (!strcmp(name, "/"))
-                snprintf(tmp, sizeof(tmp), "/%s", de->d_name);
-            else
-                snprintf(tmp, sizeof(tmp), "%s/%s", name, de->d_name);
-
-            /*
-             * If the name ends in a '/', use stat() so we treat it like a
-             * directory even if it's a symlink.
-             */
-            if (tmp[strlen(tmp)-1] == '/')
-                err = stat(tmp, &s);
-            else
-                err = lstat(tmp, &s);
-
-            if (err < 0) {
-                perror(tmp);
-                closedir(d);
-                return -1;
-            }
-
-            if (S_ISDIR(s.st_mode)) {
-                strlist_append_dup(&subdirs, tmp);
-            }
-        }
-        strlist_sort(&subdirs);
-        STRLIST_FOREACH(&subdirs, path, {
-            printf("\n%s:\n", path);
-            listdir(path, flags);
-        });
-        strlist_done(&subdirs);
-    }
-
-    closedir(d);
-    return 0;
-}
-
-static int listpath(const char *name, int flags)
-{
-    struct stat s;
-    int err;
-
-    /*
-     * If the name ends in a '/', use stat() so we treat it like a
-     * directory even if it's a symlink.
-     */
-    if (name[strlen(name)-1] == '/')
-        err = stat(name, &s);
-    else
-        err = lstat(name, &s);
-
-    if (err < 0) {
-        perror(name);
-        return -1;
-    }
-
-    if ((flags & LIST_DIRECTORIES) == 0 && S_ISDIR(s.st_mode)) {
-        if (flags & LIST_RECURSIVE)
-            printf("\n%s:\n", name);
-        return listdir(name, flags);
-    } else {
-        /* yeah this calls stat() again*/
-        return listfile(NULL, name, flags);
-    }
-}
-
-int ls_main(int argc, char **argv)
-{
-    int flags = 0;
-
-    if(argc > 1) {
-        int i;
-        int err = 0;
-        strlist_t  files = STRLIST_INITIALIZER;
-
-        for (i = 1; i < argc; i++) {
-            if (argv[i][0] == '-') {
-                /* an option ? */
-                const char *arg = argv[i]+1;
-                while (arg[0]) {
-                    switch (arg[0]) {
-                    case 'l': flags |= LIST_LONG; break;
-                    case 'n': flags |= LIST_LONG | LIST_LONG_NUMERIC; break;
-                    case 's': flags |= LIST_SIZE; break;
-                    case 'R': flags |= LIST_RECURSIVE; break;
-                    case 'd': flags |= LIST_DIRECTORIES; break;
-                    case 'Z': flags |= LIST_MACLABEL; break;
-                    case 'a': flags |= LIST_ALL; break;
-                    case 'F': flags |= LIST_CLASSIFY; break;
-                    case 'i': flags |= LIST_INODE; break;
-                    default:
-                        fprintf(stderr, "%s: Unknown option '-%c'. Aborting.\n", "ls", arg[0]);
-                        exit(1);
-                    }
-                    arg++;
-                }
-            } else {
-                /* not an option ? */
-                strlist_append_dup(&files, argv[i]);
-            }
-        }
-
-        if (files.count > 0) {
-            STRLIST_FOREACH(&files, path, {
-                if (listpath(path, flags) != 0) {
-                    err = EXIT_FAILURE;
-                }
-            });
-            strlist_done(&files);
-            return err;
-        }
-    }
-
-    // list working directory if no files or directories were specified
-    return listpath(".", flags);
-}