summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTreehugger Robot <treehugger-gerrit@google.com>2018-07-20 18:35:25 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2018-07-20 18:35:25 +0000
commitc23280a1e381c7b9aa5db8fbb338fea8940d0e98 (patch)
treeaf94bebf63b12af0792b61a17d71850b56577338
parent74be24d696f2d67293de6b9bb6e715c1728abed7 (diff)
parent6150a37dbe6c683285e98d7bd7ac1abf17ec84b4 (diff)
downloadsystem_core-c23280a1e381c7b9aa5db8fbb338fea8940d0e98.tar.gz
system_core-c23280a1e381c7b9aa5db8fbb338fea8940d0e98.tar.bz2
system_core-c23280a1e381c7b9aa5db8fbb338fea8940d0e98.zip
Merge changes Iccfe3bd4,I6380245b,I20d9f2fe
* changes: adb: Remove most C-style allocations adb: Modernize the service creation adb: Preserve the original mount flags when remounting
-rw-r--r--adb/adb.cpp27
-rw-r--r--adb/adb.h5
-rw-r--r--adb/adb_listeners.cpp7
-rw-r--r--adb/client/commandline.cpp22
-rw-r--r--adb/daemon/file_sync_service.cpp5
-rw-r--r--adb/daemon/framebuffer_service.cpp13
-rw-r--r--adb/daemon/framebuffer_service.h24
-rw-r--r--adb/daemon/remount_service.cpp70
-rw-r--r--adb/daemon/set_verity_enable_state_service.cpp26
-rw-r--r--adb/daemon/set_verity_enable_state_service.h24
-rw-r--r--adb/file_sync_service.h4
-rw-r--r--adb/remount_service.h4
-rw-r--r--adb/services.cpp235
-rw-r--r--adb/sysdeps/memory.h29
-rw-r--r--adb/transport.cpp94
-rw-r--r--adb/transport.h12
-rw-r--r--adb/transport_test.cpp6
-rw-r--r--adb/types.h19
18 files changed, 341 insertions, 285 deletions
diff --git a/adb/adb.cpp b/adb/adb.cpp
index 20d0db5fb..9b4870280 100644
--- a/adb/adb.cpp
+++ b/adb/adb.cpp
@@ -264,15 +264,6 @@ void send_connect(atransport* t) {
send_packet(cp, t);
}
-// qual_overwrite is used to overwrite a qualifier string. dst is a
-// pointer to a char pointer. It is assumed that if *dst is non-NULL, it
-// was malloc'ed and needs to freed. *dst will be set to a dup of src.
-// TODO: switch to std::string for these atransport fields instead.
-static void qual_overwrite(char** dst, const std::string& src) {
- free(*dst);
- *dst = strdup(src.c_str());
-}
-
void parse_banner(const std::string& banner, atransport* t) {
D("parse_banner: %s", banner.c_str());
@@ -296,11 +287,11 @@ void parse_banner(const std::string& banner, atransport* t) {
const std::string& key = key_value[0];
const std::string& value = key_value[1];
if (key == "ro.product.name") {
- qual_overwrite(&t->product, value);
+ t->product = value;
} else if (key == "ro.product.model") {
- qual_overwrite(&t->model, value);
+ t->model = value;
} else if (key == "ro.product.device") {
- qual_overwrite(&t->device, value);
+ t->device = value;
} else if (key == "features") {
t->SetFeatures(value);
}
@@ -424,8 +415,8 @@ void handle_packet(apacket *p, atransport *t)
/* 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",
- p->msg.arg0, p->msg.arg1, s->peer->id, p->msg.arg1, t->serial);
+ 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.c_str());
}
} else {
// When receiving A_OKAY from device for A_OPEN request, the host server may
@@ -451,8 +442,8 @@ void handle_packet(apacket *p, atransport *t)
* 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",
- p->msg.arg1, t->serial, s->peer->transport->serial);
+ D("Invalid A_CLSE(0, %u) from transport %s, expected transport %s", p->msg.arg1,
+ t->serial.c_str(), s->peer->transport->serial.c_str());
} else {
s->close(s);
}
@@ -1171,7 +1162,7 @@ int handle_host_request(const char* service, TransportType type, const char* ser
std::string error;
atransport* t = acquire_one_transport(type, serial, transport_id, nullptr, &error);
if (t) {
- return SendOkay(reply_fd, t->serial ? t->serial : "unknown");
+ return SendOkay(reply_fd, !t->serial.empty() ? t->serial : "unknown");
} else {
return SendFail(reply_fd, error);
}
@@ -1180,7 +1171,7 @@ int handle_host_request(const char* service, TransportType type, const char* ser
std::string error;
atransport* t = acquire_one_transport(type, serial, transport_id, nullptr, &error);
if (t) {
- return SendOkay(reply_fd, t->devpath ? t->devpath : "unknown");
+ return SendOkay(reply_fd, !t->devpath.empty() ? t->devpath : "unknown");
} else {
return SendFail(reply_fd, error);
}
diff --git a/adb/adb.h b/adb/adb.h
index c8841661d..7e9af9e3f 100644
--- a/adb/adb.h
+++ b/adb/adb.h
@@ -156,11 +156,6 @@ int create_jdwp_connection_fd(int jdwp_pid);
int handle_forward_request(const char* service, atransport* transport, int reply_fd);
-#if !ADB_HOST
-void framebuffer_service(int fd, void* cookie);
-void set_verity_enabled_state_service(int fd, void* cookie);
-#endif
-
/* packet allocator */
apacket* get_apacket(void);
void put_apacket(apacket* p);
diff --git a/adb/adb_listeners.cpp b/adb/adb_listeners.cpp
index ea5a44e46..f4a92e360 100644
--- a/adb/adb_listeners.cpp
+++ b/adb/adb_listeners.cpp
@@ -136,9 +136,10 @@ std::string format_listeners() EXCLUDES(listener_list_mutex) {
}
// <device-serial> " " <local-name> " " <remote-name> "\n"
// Entries from "adb reverse" have no serial.
- android::base::StringAppendF(&result, "%s %s %s\n",
- l->transport->serial ? l->transport->serial : "(reverse)",
- l->local_name.c_str(), l->connect_to.c_str());
+ android::base::StringAppendF(
+ &result, "%s %s %s\n",
+ !l->transport->serial.empty() ? l->transport->serial.c_str() : "(reverse)",
+ l->local_name.c_str(), l->connect_to.c_str());
}
return result;
}
diff --git a/adb/client/commandline.cpp b/adb/client/commandline.cpp
index 80d0dd3d1..7791895f6 100644
--- a/adb/client/commandline.cpp
+++ b/adb/client/commandline.cpp
@@ -362,9 +362,8 @@ static void stdinout_raw_epilogue(int inFd, int outFd, int old_stdin_mode, int o
}
static void copy_to_file(int inFd, int outFd) {
- const size_t BUFSIZE = 32 * 1024;
- char* buf = (char*) malloc(BUFSIZE);
- if (buf == nullptr) fatal("couldn't allocate buffer for copy_to_file");
+ constexpr size_t BUFSIZE = 32 * 1024;
+ std::vector<char> buf(BUFSIZE);
int len;
long total = 0;
int old_stdin_mode = -1;
@@ -376,9 +375,9 @@ static void copy_to_file(int inFd, int outFd) {
while (true) {
if (inFd == STDIN_FILENO) {
- len = unix_read(inFd, buf, BUFSIZE);
+ len = unix_read(inFd, buf.data(), BUFSIZE);
} else {
- len = adb_read(inFd, buf, BUFSIZE);
+ len = adb_read(inFd, buf.data(), BUFSIZE);
}
if (len == 0) {
D("copy_to_file() : read 0 bytes; exiting");
@@ -389,10 +388,10 @@ static void copy_to_file(int inFd, int outFd) {
break;
}
if (outFd == STDOUT_FILENO) {
- fwrite(buf, 1, len, stdout);
+ fwrite(buf.data(), 1, len, stdout);
fflush(stdout);
} else {
- adb_write(outFd, buf, len);
+ adb_write(outFd, buf.data(), len);
}
total += len;
}
@@ -400,7 +399,6 @@ static void copy_to_file(int inFd, int outFd) {
stdinout_raw_epilogue(inFd, outFd, old_stdin_mode, old_stdout_mode);
D("copy_to_file() finished after %lu bytes", total);
- free(buf);
}
static void send_window_size_change(int fd, std::unique_ptr<ShellProtocol>& shell) {
@@ -1142,24 +1140,22 @@ static int logcat(int argc, const char** argv) {
static void write_zeros(int bytes, int fd) {
int old_stdin_mode = -1;
int old_stdout_mode = -1;
- char* buf = (char*) calloc(1, bytes);
- if (buf == nullptr) fatal("couldn't allocate buffer for write_zeros");
+ std::vector<char> buf(bytes);
D("write_zeros(%d) -> %d", bytes, fd);
stdinout_raw_prologue(-1, fd, old_stdin_mode, old_stdout_mode);
if (fd == STDOUT_FILENO) {
- fwrite(buf, 1, bytes, stdout);
+ fwrite(buf.data(), 1, bytes, stdout);
fflush(stdout);
} else {
- adb_write(fd, buf, bytes);
+ adb_write(fd, buf.data(), bytes);
}
stdinout_raw_prologue(-1, fd, old_stdin_mode, old_stdout_mode);
D("write_zeros() finished");
- free(buf);
}
static int backup(int argc, const char** argv) {
diff --git a/adb/daemon/file_sync_service.cpp b/adb/daemon/file_sync_service.cpp
index f7be8f94b..0b713631e 100644
--- a/adb/daemon/file_sync_service.cpp
+++ b/adb/daemon/file_sync_service.cpp
@@ -525,12 +525,11 @@ static bool handle_sync_command(int fd, std::vector<char>& buffer) {
return true;
}
-void file_sync_service(int fd, void*) {
+void file_sync_service(android::base::unique_fd fd) {
std::vector<char> buffer(SYNC_DATA_MAX);
- while (handle_sync_command(fd, buffer)) {
+ while (handle_sync_command(fd.get(), buffer)) {
}
D("sync: done");
- adb_close(fd);
}
diff --git a/adb/daemon/framebuffer_service.cpp b/adb/daemon/framebuffer_service.cpp
index 20e03f9c7..9a620ab7f 100644
--- a/adb/daemon/framebuffer_service.cpp
+++ b/adb/daemon/framebuffer_service.cpp
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+#include "framebuffer_service.h"
+
#include <errno.h>
#include <fcntl.h>
#include <linux/fb.h>
@@ -55,8 +57,7 @@ struct fbinfo {
unsigned int alpha_length;
} __attribute__((packed));
-void framebuffer_service(int fd, void *cookie)
-{
+void framebuffer_service(android::base::unique_fd fd) {
struct fbinfo fbinfo;
unsigned int i, bsize;
char buf[640];
@@ -65,7 +66,7 @@ void framebuffer_service(int fd, void *cookie)
int fds[2];
pid_t pid;
- if (pipe2(fds, O_CLOEXEC) < 0) goto pipefail;
+ if (pipe2(fds, O_CLOEXEC) < 0) return;
pid = fork();
if (pid < 0) goto done;
@@ -168,7 +169,7 @@ void framebuffer_service(int fd, void *cookie)
}
/* write header */
- if(!WriteFdExactly(fd, &fbinfo, sizeof(fbinfo))) goto done;
+ if (!WriteFdExactly(fd.get(), &fbinfo, sizeof(fbinfo))) goto done;
/* write data */
for(i = 0; i < fbinfo.size; i += bsize) {
@@ -176,13 +177,11 @@ void framebuffer_service(int fd, void *cookie)
if (i + bsize > fbinfo.size)
bsize = fbinfo.size - i;
if(!ReadFdExactly(fd_screencap, buf, bsize)) goto done;
- if(!WriteFdExactly(fd, buf, bsize)) goto done;
+ if (!WriteFdExactly(fd.get(), buf, bsize)) goto done;
}
done:
adb_close(fds[0]);
TEMP_FAILURE_RETRY(waitpid(pid, nullptr, 0));
-pipefail:
- adb_close(fd);
}
diff --git a/adb/daemon/framebuffer_service.h b/adb/daemon/framebuffer_service.h
new file mode 100644
index 000000000..d99c6fe14
--- /dev/null
+++ b/adb/daemon/framebuffer_service.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2018 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 _DAEMON_FRAMEBUFFER_SERVICE_H_
+#define _DAEMON_FRAMEBUFFER_SERVICE_H_
+
+#include <android-base/unique_fd.h>
+
+void framebuffer_service(android::base::unique_fd fd);
+
+#endif // _DAEMON_FRAMEBUFFER_SERVICE_H_
diff --git a/adb/daemon/remount_service.cpp b/adb/daemon/remount_service.cpp
index 830b35d63..dfdc365e3 100644
--- a/adb/daemon/remount_service.cpp
+++ b/adb/daemon/remount_service.cpp
@@ -26,6 +26,7 @@
#include <stdlib.h>
#include <string.h>
#include <sys/mount.h>
+#include <sys/statvfs.h>
#include <sys/vfs.h>
#include <unistd.h>
@@ -43,6 +44,7 @@
#include "adb_unique_fd.h"
#include "adb_utils.h"
#include "fs_mgr.h"
+#include "set_verity_enable_state_service.h"
// Returns the device used to mount a directory in /proc/mounts.
static std::string find_proc_mount(const char* dir) {
@@ -145,6 +147,17 @@ static bool can_unshare_blocks(int fd, const char* dev) {
return true;
}
+static unsigned long get_mount_flags(int fd, const char* dir) {
+ struct statvfs st_vfs;
+ if (statvfs(dir, &st_vfs) == -1) {
+ // Even though we could not get the original mount flags, assume that
+ // the mount was originally read-only.
+ WriteFdFmt(fd, "statvfs of the %s mount failed: %s.\n", dir, strerror(errno));
+ return MS_RDONLY;
+ }
+ return st_vfs.f_flag;
+}
+
static bool remount_partition(int fd, const char* dir) {
if (!directory_exists(dir)) {
return true;
@@ -163,14 +176,23 @@ static bool remount_partition(int fd, const char* dir) {
dir, dev.c_str(), strerror(errno));
return false;
}
- if (mount(dev.c_str(), dir, "none", MS_REMOUNT | MS_BIND, nullptr) == -1) {
+
+ unsigned long remount_flags = get_mount_flags(fd, dir);
+ if ((remount_flags & MS_RDONLY) == 0) {
+ // Mount is already writable.
+ return true;
+ }
+ remount_flags &= ~MS_RDONLY;
+ remount_flags |= MS_REMOUNT;
+
+ if (mount(dev.c_str(), dir, "none", remount_flags | MS_BIND, nullptr) == -1) {
// This is useful for cases where the superblock is already marked as
// read-write, but the mount itself is read-only, such as containers
// where the remount with just MS_REMOUNT is forbidden by the kernel.
WriteFdFmt(fd, "remount of the %s mount failed: %s.\n", dir, strerror(errno));
return false;
}
- if (mount(dev.c_str(), dir, "none", MS_REMOUNT, nullptr) == -1) {
+ if (mount(dev.c_str(), dir, "none", remount_flags, nullptr) == -1) {
WriteFdFmt(fd, "remount of the %s superblock failed: %s\n", dir, strerror(errno));
return false;
}
@@ -197,14 +219,11 @@ static void reboot_for_remount(int fd, bool need_fsck) {
android::base::SetProperty(ANDROID_RB_PROPERTY, reboot_cmd.c_str());
}
-void remount_service(int fd, void* cookie) {
- unique_fd close_fd(fd);
-
- const char* cmd = reinterpret_cast<const char*>(cookie);
- bool user_requested_reboot = cmd && !strcmp(cmd, "-R");
+void remount_service(android::base::unique_fd fd, const std::string& cmd) {
+ bool user_requested_reboot = cmd != "-R";
if (getuid() != 0) {
- WriteFdExactly(fd, "Not running as root. Try \"adb root\" first.\n");
+ WriteFdExactly(fd.get(), "Not running as root. Try \"adb root\" first.\n");
return;
}
@@ -225,7 +244,7 @@ void remount_service(int fd, void* cookie) {
if (dev.empty() || !fs_has_shared_blocks(dev.c_str())) {
continue;
}
- if (can_unshare_blocks(fd, dev.c_str())) {
+ if (can_unshare_blocks(fd.get(), dev.c_str())) {
dedup.emplace(partition);
}
}
@@ -236,12 +255,12 @@ void remount_service(int fd, void* cookie) {
if (user_requested_reboot) {
if (!dedup.empty() || verity_enabled) {
if (verity_enabled) {
- set_verity_enabled_state_service(fd, nullptr);
+ set_verity_enabled_state_service(android::base::unique_fd(dup(fd.get())), false);
}
- reboot_for_remount(fd, !dedup.empty());
+ reboot_for_remount(fd.get(), !dedup.empty());
return;
}
- WriteFdExactly(fd, "No reboot needed, skipping -R.\n");
+ WriteFdExactly(fd.get(), "No reboot needed, skipping -R.\n");
}
// If we need to disable-verity, but we also need to perform a recovery
@@ -250,17 +269,14 @@ void remount_service(int fd, void* cookie) {
if (verity_enabled && dedup.empty()) {
// Allow remount but warn of likely bad effects
bool both = system_verified && vendor_verified;
- WriteFdFmt(fd,
- "dm_verity is enabled on the %s%s%s partition%s.\n",
- system_verified ? "system" : "",
- both ? " and " : "",
- vendor_verified ? "vendor" : "",
- both ? "s" : "");
- WriteFdExactly(fd,
+ WriteFdFmt(fd.get(), "dm_verity is enabled on the %s%s%s partition%s.\n",
+ system_verified ? "system" : "", both ? " and " : "",
+ vendor_verified ? "vendor" : "", both ? "s" : "");
+ WriteFdExactly(fd.get(),
"Use \"adb disable-verity\" to disable verity.\n"
"If you do not, remount may succeed, however, you will still "
"not be able to write to these volumes.\n");
- WriteFdExactly(fd,
+ WriteFdExactly(fd.get(),
"Alternately, use \"adb remount -R\" to disable verity "
"and automatically reboot.\n");
}
@@ -271,29 +287,29 @@ void remount_service(int fd, void* cookie) {
if (dedup.count(partition)) {
continue;
}
- success &= remount_partition(fd, partition.c_str());
+ success &= remount_partition(fd.get(), partition.c_str());
}
if (!dedup.empty()) {
- WriteFdExactly(fd,
+ WriteFdExactly(fd.get(),
"The following partitions are deduplicated and cannot "
"yet be remounted:\n");
for (const std::string& name : dedup) {
- WriteFdFmt(fd, " %s\n", name.c_str());
+ WriteFdFmt(fd.get(), " %s\n", name.c_str());
}
- WriteFdExactly(fd,
+ WriteFdExactly(fd.get(),
"To reboot and un-deduplicate the listed partitions, "
"please retry with adb remount -R.\n");
if (system_verified || vendor_verified) {
- WriteFdExactly(fd, "Note: verity will be automatically disabled after reboot.\n");
+ WriteFdExactly(fd.get(), "Note: verity will be automatically disabled after reboot.\n");
}
return;
}
if (!success) {
- WriteFdExactly(fd, "remount failed\n");
+ WriteFdExactly(fd.get(), "remount failed\n");
} else {
- WriteFdExactly(fd, "remount succeeded\n");
+ WriteFdExactly(fd.get(), "remount succeeded\n");
}
}
diff --git a/adb/daemon/set_verity_enable_state_service.cpp b/adb/daemon/set_verity_enable_state_service.cpp
index dbeee280d..0f804e933 100644
--- a/adb/daemon/set_verity_enable_state_service.cpp
+++ b/adb/daemon/set_verity_enable_state_service.cpp
@@ -16,6 +16,7 @@
#define TRACE_TAG ADB
+#include "set_verity_enable_state_service.h"
#include "sysdeps.h"
#include <fcntl.h>
@@ -25,8 +26,8 @@
#include <stdio.h>
#include <sys/stat.h>
-#include "android-base/properties.h"
-#include "android-base/stringprintf.h"
+#include <android-base/properties.h>
+#include <android-base/stringprintf.h>
#include <log/log_properties.h>
#include "adb.h"
@@ -131,12 +132,9 @@ static bool set_avb_verity_enabled_state(int fd, AvbOps* ops, bool enable_verity
return true;
}
-void set_verity_enabled_state_service(int fd, void* cookie) {
- unique_fd closer(fd);
+void set_verity_enabled_state_service(android::base::unique_fd fd, bool enable) {
bool any_changed = false;
- bool enable = (cookie != nullptr);
-
// Figure out if we're using VB1.0 or VB2.0 (aka AVB) - by
// contract, androidboot.vbmeta.digest is set by the bootloader
// when using AVB).
@@ -147,12 +145,12 @@ void set_verity_enabled_state_service(int fd, void* cookie) {
// VB1.0 dm-verity is only enabled on certain builds.
if (!using_avb) {
if (!kAllowDisableVerity) {
- WriteFdFmt(fd, "%s-verity only works for userdebug builds\n",
+ WriteFdFmt(fd.get(), "%s-verity only works for userdebug builds\n",
enable ? "enable" : "disable");
}
if (!android::base::GetBoolProperty("ro.secure", false)) {
- WriteFdFmt(fd, "verity not enabled - ENG build\n");
+ WriteFdFmt(fd.get(), "verity not enabled - ENG build\n");
return;
}
}
@@ -160,7 +158,7 @@ void set_verity_enabled_state_service(int fd, void* cookie) {
// Should never be possible to disable dm-verity on a USER build
// regardless of using AVB or VB1.0.
if (!__android_log_is_debuggable()) {
- WriteFdFmt(fd, "verity cannot be disabled/enabled - USER build\n");
+ WriteFdFmt(fd.get(), "verity cannot be disabled/enabled - USER build\n");
return;
}
@@ -168,10 +166,10 @@ void set_verity_enabled_state_service(int fd, void* cookie) {
// Yep, the system is using AVB.
AvbOps* ops = avb_ops_user_new();
if (ops == nullptr) {
- WriteFdFmt(fd, "Error getting AVB ops\n");
+ WriteFdFmt(fd.get(), "Error getting AVB ops\n");
return;
}
- if (set_avb_verity_enabled_state(fd, ops, enable)) {
+ if (set_avb_verity_enabled_state(fd.get(), ops, enable)) {
any_changed = true;
}
avb_ops_user_free(ops);
@@ -181,14 +179,14 @@ void set_verity_enabled_state_service(int fd, void* cookie) {
// read all fstab entries at once from all sources
fstab = fs_mgr_read_fstab_default();
if (!fstab) {
- WriteFdFmt(fd, "Failed to read fstab\nMaybe run adb root?\n");
+ WriteFdFmt(fd.get(), "Failed to read fstab\nMaybe run adb root?\n");
return;
}
// Loop through entries looking for ones that vold manages.
for (int i = 0; i < fstab->num_entries; i++) {
if (fs_mgr_is_verified(&fstab->recs[i])) {
- if (set_verity_enabled_state(fd, fstab->recs[i].blk_device,
+ if (set_verity_enabled_state(fd.get(), fstab->recs[i].blk_device,
fstab->recs[i].mount_point, enable)) {
any_changed = true;
}
@@ -197,6 +195,6 @@ void set_verity_enabled_state_service(int fd, void* cookie) {
}
if (any_changed) {
- WriteFdFmt(fd, "Now reboot your device for settings to take effect\n");
+ WriteFdFmt(fd.get(), "Now reboot your device for settings to take effect\n");
}
}
diff --git a/adb/daemon/set_verity_enable_state_service.h b/adb/daemon/set_verity_enable_state_service.h
new file mode 100644
index 000000000..9f84f35ea
--- /dev/null
+++ b/adb/daemon/set_verity_enable_state_service.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2018 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 _DAEMON_SET_VERITY_ENABLED_STATE_SERVICE_H_
+#define _DAEMON_SET_VERITY_ENABLED_STATE_SERVICE_H_
+
+#include <android-base/unique_fd.h>
+
+void set_verity_enabled_state_service(android::base::unique_fd fd, bool enable);
+
+#endif // _DAEMON_SET_VERITY_ENABLED_STATE_SERVICE_H_
diff --git a/adb/file_sync_service.h b/adb/file_sync_service.h
index 6606efdfb..608b3ada3 100644
--- a/adb/file_sync_service.h
+++ b/adb/file_sync_service.h
@@ -20,6 +20,8 @@
#include <string>
#include <vector>
+#include <android-base/unique_fd.h>
+
#define MKID(a,b,c,d) ((a) | ((b) << 8) | ((c) << 16) | ((d) << 24))
#define ID_LSTAT_V1 MKID('S','T','A','T')
@@ -79,7 +81,7 @@ union syncmsg {
} status;
};
-void file_sync_service(int fd, void* cookie);
+void file_sync_service(android::base::unique_fd fd);
bool do_sync_ls(const char* path);
bool do_sync_push(const std::vector<const char*>& srcs, const char* dst, bool sync);
bool do_sync_pull(const std::vector<const char*>& srcs, const char* dst,
diff --git a/adb/remount_service.h b/adb/remount_service.h
index 7bda1be20..45821eef2 100644
--- a/adb/remount_service.h
+++ b/adb/remount_service.h
@@ -19,7 +19,9 @@
#include <string>
+#include <android-base/unique_fd.h>
+
bool make_block_device_writable(const std::string&);
-void remount_service(int, void*);
+void remount_service(android::base::unique_fd, const std::string&);
#endif
diff --git a/adb/services.cpp b/adb/services.cpp
index 1fa7ecc07..3d418cb92 100644
--- a/adb/services.cpp
+++ b/adb/services.cpp
@@ -37,6 +37,7 @@
#include <android-base/parsenetaddress.h>
#include <android-base/stringprintf.h>
#include <android-base/strings.h>
+#include <android-base/unique_fd.h>
#include <cutils/sockets.h>
#if !ADB_HOST
@@ -49,6 +50,10 @@
#include "adb.h"
#include "adb_io.h"
#include "adb_utils.h"
+#if !ADB_HOST
+#include "daemon/framebuffer_service.h"
+#include "daemon/set_verity_enable_state_service.h"
+#endif
#include "file_sync_service.h"
#include "remount_service.h"
#include "services.h"
@@ -57,81 +62,67 @@
#include "sysdeps.h"
#include "transport.h"
-struct stinfo {
- const char* service_name;
- void (*func)(int fd, void *cookie);
- int fd;
- void *cookie;
-};
+namespace {
-static void service_bootstrap_func(void* x) {
- stinfo* sti = reinterpret_cast<stinfo*>(x);
- adb_thread_setname(android::base::StringPrintf("%s svc %d", sti->service_name, sti->fd));
- sti->func(sti->fd, sti->cookie);
- free(sti);
+void service_bootstrap_func(std::string service_name,
+ std::function<void(android::base::unique_fd)> func,
+ android::base::unique_fd fd) {
+ adb_thread_setname(android::base::StringPrintf("%s svc %d", service_name.c_str(), fd.get()));
+ func(std::move(fd));
}
#if !ADB_HOST
-void restart_root_service(int fd, void *cookie) {
+void restart_root_service(android::base::unique_fd fd) {
if (getuid() == 0) {
- WriteFdExactly(fd, "adbd is already running as root\n");
- adb_close(fd);
- } else {
- if (!__android_log_is_debuggable()) {
- WriteFdExactly(fd, "adbd cannot run as root in production builds\n");
- adb_close(fd);
- return;
- }
-
- android::base::SetProperty("service.adb.root", "1");
- WriteFdExactly(fd, "restarting adbd as root\n");
- adb_close(fd);
+ WriteFdExactly(fd.get(), "adbd is already running as root\n");
+ return;
}
+ if (!__android_log_is_debuggable()) {
+ WriteFdExactly(fd.get(), "adbd cannot run as root in production builds\n");
+ return;
+ }
+
+ android::base::SetProperty("service.adb.root", "1");
+ WriteFdExactly(fd.get(), "restarting adbd as root\n");
}
-void restart_unroot_service(int fd, void *cookie) {
+void restart_unroot_service(android::base::unique_fd fd) {
if (getuid() != 0) {
- WriteFdExactly(fd, "adbd not running as root\n");
- adb_close(fd);
- } else {
- android::base::SetProperty("service.adb.root", "0");
- WriteFdExactly(fd, "restarting adbd as non root\n");
- adb_close(fd);
+ WriteFdExactly(fd.get(), "adbd not running as root\n");
+ return;
}
+ android::base::SetProperty("service.adb.root", "0");
+ WriteFdExactly(fd.get(), "restarting adbd as non root\n");
}
-void restart_tcp_service(int fd, void *cookie) {
- int port = (int) (uintptr_t) cookie;
+void restart_tcp_service(android::base::unique_fd fd, int port) {
if (port <= 0) {
- WriteFdFmt(fd, "invalid port %d\n", port);
- adb_close(fd);
+ WriteFdFmt(fd.get(), "invalid port %d\n", port);
return;
}
android::base::SetProperty("service.adb.tcp.port", android::base::StringPrintf("%d", port));
- WriteFdFmt(fd, "restarting in TCP mode port: %d\n", port);
- adb_close(fd);
+ WriteFdFmt(fd.get(), "restarting in TCP mode port: %d\n", port);
}
-void restart_usb_service(int fd, void *cookie) {
+void restart_usb_service(android::base::unique_fd fd) {
android::base::SetProperty("service.adb.tcp.port", "0");
- WriteFdExactly(fd, "restarting in USB mode\n");
- adb_close(fd);
+ WriteFdExactly(fd.get(), "restarting in USB mode\n");
}
-static bool reboot_service_impl(int fd, const char* arg) {
- const char* reboot_arg = arg;
+bool reboot_service_impl(android::base::unique_fd fd, const std::string& arg) {
+ std::string reboot_arg = arg;
bool auto_reboot = false;
- if (strcmp(reboot_arg, "sideload-auto-reboot") == 0) {
+ if (reboot_arg == "sideload-auto-reboot") {
auto_reboot = true;
reboot_arg = "sideload";
}
// It reboots into sideload mode by setting "--sideload" or "--sideload_auto_reboot"
// in the command file.
- if (strcmp(reboot_arg, "sideload") == 0) {
+ if (reboot_arg == "sideload") {
if (getuid() != 0) {
WriteFdExactly(fd, "'adb root' is required for 'adb reboot sideload'.\n");
return false;
@@ -151,8 +142,8 @@ static bool reboot_service_impl(int fd, const char* arg) {
sync();
- if (!reboot_arg || !reboot_arg[0]) reboot_arg = "adb";
- std::string reboot_string = android::base::StringPrintf("reboot,%s", reboot_arg);
+ if (reboot_arg.empty()) reboot_arg = "adb";
+ std::string reboot_string = android::base::StringPrintf("reboot,%s", reboot_arg.c_str());
if (!android::base::SetProperty(ANDROID_RB_PROPERTY, reboot_string)) {
WriteFdFmt(fd, "reboot (%s) failed\n", reboot_string.c_str());
return false;
@@ -161,23 +152,19 @@ static bool reboot_service_impl(int fd, const char* arg) {
return true;
}
-void reboot_service(int fd, void* arg) {
- if (reboot_service_impl(fd, static_cast<const char*>(arg))) {
- // Don't return early. Give the reboot command time to take effect
- // to avoid messing up scripts which do "adb reboot && adb wait-for-device"
- while (true) {
- pause();
- }
+void reboot_service(android::base::unique_fd fd, const std::string& arg) {
+ if (!reboot_service_impl(std::move(fd), arg)) {
+ return;
+ }
+ // Don't return early. Give the reboot command time to take effect
+ // to avoid messing up scripts which do "adb reboot && adb wait-for-device"
+ while (true) {
+ pause();
}
-
- free(arg);
- adb_close(fd);
}
-static void reconnect_service(int fd, void* arg) {
+void reconnect_service(android::base::unique_fd fd, atransport* t) {
WriteFdExactly(fd, "done");
- adb_close(fd);
- atransport* t = static_cast<atransport*>(arg);
kick_transport(t);
}
@@ -197,7 +184,7 @@ int reverse_service(const char* command, atransport* transport) {
// Shell service string can look like:
// shell[,arg1,arg2,...]:[command]
-static int ShellService(const std::string& args, const atransport* transport) {
+int ShellService(const std::string& args, const atransport* transport) {
size_t delimiter_index = args.find(':');
if (delimiter_index == std::string::npos) {
LOG(ERROR) << "No ':' found in shell service arguments: " << args;
@@ -236,16 +223,17 @@ static int ShellService(const std::string& args, const atransport* transport) {
#endif // !ADB_HOST
-static int create_service_thread(const char* service_name, void (*func)(int, void*), void* cookie) {
+android::base::unique_fd create_service_thread(const char* service_name,
+ std::function<void(android::base::unique_fd)> func) {
int s[2];
if (adb_socketpair(s)) {
printf("cannot create service socket pair\n");
- return -1;
+ return android::base::unique_fd();
}
D("socketpair: (%d,%d)", s[0], s[1]);
#if !ADB_HOST
- if (func == &file_sync_service) {
+ if (strcmp(service_name, "sync") == 0) {
// Set file sync service socket to maximum size
int max_buf = LINUX_MAX_SOCKET_SIZE;
adb_setsockopt(s[0], SOL_SOCKET, SO_SNDBUF, &max_buf, sizeof(max_buf));
@@ -253,21 +241,14 @@ static int create_service_thread(const char* service_name, void (*func)(int, voi
}
#endif // !ADB_HOST
- stinfo* sti = reinterpret_cast<stinfo*>(malloc(sizeof(stinfo)));
- if (sti == nullptr) {
- fatal("cannot allocate stinfo");
- }
- sti->service_name = service_name;
- sti->func = func;
- sti->cookie = cookie;
- sti->fd = s[1];
-
- std::thread(service_bootstrap_func, sti).detach();
+ std::thread(service_bootstrap_func, service_name, func, android::base::unique_fd(s[1])).detach();
D("service thread started, %d:%d",s[0], s[1]);
- return s[0];
+ return android::base::unique_fd(s[0]);
}
+} // namespace
+
int service_to_fd(const char* name, atransport* transport) {
int ret = -1;
@@ -280,54 +261,60 @@ int service_to_fd(const char* name, atransport* transport) {
#if !ADB_HOST
} else if(!strncmp("dev:", name, 4)) {
ret = unix_open(name + 4, O_RDWR | O_CLOEXEC);
- } else if(!strncmp(name, "framebuffer:", 12)) {
- ret = create_service_thread("fb", framebuffer_service, nullptr);
+ } else if (!strncmp(name, "framebuffer:", 12)) {
+ ret = create_service_thread("fb", framebuffer_service).release();
} else if (!strncmp(name, "jdwp:", 5)) {
- ret = create_jdwp_connection_fd(atoi(name+5));
- } else if(!strncmp(name, "shell", 5)) {
+ ret = create_jdwp_connection_fd(atoi(name + 5));
+ } else if (!strncmp(name, "shell", 5)) {
ret = ShellService(name + 5, transport);
- } else if(!strncmp(name, "exec:", 5)) {
+ } else if (!strncmp(name, "exec:", 5)) {
ret = StartSubprocess(name + 5, nullptr, SubprocessType::kRaw, SubprocessProtocol::kNone);
- } else if(!strncmp(name, "sync:", 5)) {
- ret = create_service_thread("sync", file_sync_service, nullptr);
- } else if(!strncmp(name, "remount:", 8)) {
- const char* options = name + strlen("remount:");
- void* cookie = const_cast<void*>(reinterpret_cast<const void*>(options));
- ret = create_service_thread("remount", remount_service, cookie);
- } else if(!strncmp(name, "reboot:", 7)) {
- void* arg = strdup(name + 7);
- if (arg == NULL) return -1;
- ret = create_service_thread("reboot", reboot_service, arg);
- if (ret < 0) free(arg);
- } else if(!strncmp(name, "root:", 5)) {
- ret = create_service_thread("root", restart_root_service, nullptr);
- } else if(!strncmp(name, "unroot:", 7)) {
- ret = create_service_thread("unroot", restart_unroot_service, nullptr);
- } else if(!strncmp(name, "backup:", 7)) {
- ret = StartSubprocess(android::base::StringPrintf("/system/bin/bu backup %s",
- (name + 7)).c_str(),
- nullptr, SubprocessType::kRaw, SubprocessProtocol::kNone);
- } else if(!strncmp(name, "restore:", 8)) {
+ } else if (!strncmp(name, "sync:", 5)) {
+ ret = create_service_thread("sync", file_sync_service).release();
+ } else if (!strncmp(name, "remount:", 8)) {
+ std::string options(name + strlen("remount:"));
+ ret = create_service_thread("remount",
+ std::bind(remount_service, std::placeholders::_1, options))
+ .release();
+ } else if (!strncmp(name, "reboot:", 7)) {
+ std::string arg(name + strlen("reboot:"));
+ ret = create_service_thread("reboot", std::bind(reboot_service, std::placeholders::_1, arg))
+ .release();
+ } else if (!strncmp(name, "root:", 5)) {
+ ret = create_service_thread("root", restart_root_service).release();
+ } else if (!strncmp(name, "unroot:", 7)) {
+ ret = create_service_thread("unroot", restart_unroot_service).release();
+ } else if (!strncmp(name, "backup:", 7)) {
+ ret = StartSubprocess(
+ android::base::StringPrintf("/system/bin/bu backup %s", (name + 7)).c_str(),
+ nullptr, SubprocessType::kRaw, SubprocessProtocol::kNone);
+ } else if (!strncmp(name, "restore:", 8)) {
ret = StartSubprocess("/system/bin/bu restore", nullptr, SubprocessType::kRaw,
SubprocessProtocol::kNone);
- } else if(!strncmp(name, "tcpip:", 6)) {
+ } else if (!strncmp(name, "tcpip:", 6)) {
int port;
if (sscanf(name + 6, "%d", &port) != 1) {
return -1;
}
- ret = create_service_thread("tcp", restart_tcp_service, reinterpret_cast<void*>(port));
- } else if(!strncmp(name, "usb:", 4)) {
- ret = create_service_thread("usb", restart_usb_service, nullptr);
+ ret = create_service_thread("tcp",
+ std::bind(restart_tcp_service, std::placeholders::_1, port))
+ .release();
+ } else if (!strncmp(name, "usb:", 4)) {
+ ret = create_service_thread("usb", restart_usb_service).release();
} else if (!strncmp(name, "reverse:", 8)) {
ret = reverse_service(name + 8, transport);
- } else if(!strncmp(name, "disable-verity:", 15)) {
- ret = create_service_thread("verity-on", set_verity_enabled_state_service,
- reinterpret_cast<void*>(0));
- } else if(!strncmp(name, "enable-verity:", 15)) {
- ret = create_service_thread("verity-off", set_verity_enabled_state_service,
- reinterpret_cast<void*>(1));
+ } else if (!strncmp(name, "disable-verity:", 15)) {
+ ret = create_service_thread("verity-on", std::bind(set_verity_enabled_state_service,
+ std::placeholders::_1, false))
+ .release();
+ } else if (!strncmp(name, "enable-verity:", 15)) {
+ ret = create_service_thread("verity-off", std::bind(set_verity_enabled_state_service,
+ std::placeholders::_1, true))
+ .release();
} else if (!strcmp(name, "reconnect")) {
- ret = create_service_thread("reconnect", reconnect_service, transport);
+ ret = create_service_thread("reconnect",
+ std::bind(reconnect_service, std::placeholders::_1, transport))
+ .release();
#endif
}
if (ret >= 0) {
@@ -420,19 +407,16 @@ void connect_emulator(const std::string& port_spec, std::string* response) {
}
}
-static void connect_service(int fd, void* data) {
- char* host = reinterpret_cast<char*>(data);
+static void connect_service(android::base::unique_fd fd, std::string host) {
std::string response;
- if (!strncmp(host, "emu:", 4)) {
- connect_emulator(host + 4, &response);
+ if (!strncmp(host.c_str(), "emu:", 4)) {
+ connect_emulator(host.c_str() + 4, &response);
} else {
- connect_device(host, &response);
+ connect_device(host.c_str(), &response);
}
- free(host);
// Send response for emulator and device
- SendProtocolString(fd, response);
- adb_close(fd);
+ SendProtocolString(fd.get(), response);
}
#endif
@@ -445,7 +429,7 @@ asocket* host_service_to_socket(const char* name, const char* serial, TransportI
} else if (android::base::StartsWith(name, "wait-for-")) {
name += strlen("wait-for-");
- std::unique_ptr<state_info> sinfo(new state_info);
+ std::unique_ptr<state_info> sinfo = std::make_unique<state_info>();
if (sinfo == nullptr) {
fprintf(stderr, "couldn't allocate state_info: %s", strerror(errno));
return nullptr;
@@ -481,17 +465,18 @@ asocket* host_service_to_socket(const char* name, const char* serial, TransportI
return nullptr;
}
- int fd = create_service_thread("wait", wait_for_state, sinfo.get());
+ int fd = create_service_thread(
+ "wait", std::bind(wait_for_state, std::placeholders::_1, sinfo.get()))
+ .release();
if (fd != -1) {
sinfo.release();
}
return create_local_socket(fd);
} else if (!strncmp(name, "connect:", 8)) {
- char* host = strdup(name + 8);
- int fd = create_service_thread("connect", connect_service, host);
- if (fd == -1) {
- free(host);
- }
+ std::string host(name + strlen("connect:"));
+ int fd = create_service_thread("connect",
+ std::bind(connect_service, std::placeholders::_1, host))
+ .release();
return create_local_socket(fd);
}
return nullptr;
diff --git a/adb/sysdeps/memory.h b/adb/sysdeps/memory.h
index 0e4c509f6..4108aff87 100644
--- a/adb/sysdeps/memory.h
+++ b/adb/sysdeps/memory.h
@@ -23,6 +23,23 @@
// We don't have C++14 on Windows yet.
// Reimplement std::make_unique ourselves until we do.
+namespace internal {
+
+template <typename T>
+struct array_known_bounds;
+
+template <typename T>
+struct array_known_bounds<T[]> {
+ constexpr static bool value = false;
+};
+
+template <typename T, size_t N>
+struct array_known_bounds<T[N]> {
+ constexpr static bool value = true;
+};
+
+} // namespace internal
+
namespace std {
template <typename T, typename... Args>
@@ -31,6 +48,18 @@ typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type make
return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}
+template <typename T>
+typename std::enable_if<std::is_array<T>::value && !internal::array_known_bounds<T>::value,
+ std::unique_ptr<T>>::type
+make_unique(std::size_t size) {
+ return std::unique_ptr<T>(new typename std::remove_extent<T>::type[size]());
+}
+
+template <typename T, typename... Args>
+typename std::enable_if<std::is_array<T>::value && internal::array_known_bounds<T>::value,
+ std::unique_ptr<T>>::type
+make_unique(Args&&... args) = delete;
+
} // namespace std
#endif
diff --git a/adb/transport.cpp b/adb/transport.cpp
index f2c40d2f3..638940c14 100644
--- a/adb/transport.cpp
+++ b/adb/transport.cpp
@@ -173,18 +173,18 @@ void ReconnectHandler::Run() {
attempt = reconnect_queue_.front();
reconnect_queue_.pop();
if (attempt.transport->kicked()) {
- D("transport %s was kicked. giving up on it.", attempt.transport->serial);
+ D("transport %s was kicked. giving up on it.", attempt.transport->serial.c_str());
remove_transport(attempt.transport);
continue;
}
}
- D("attempting to reconnect %s", attempt.transport->serial);
+ D("attempting to reconnect %s", attempt.transport->serial.c_str());
if (!attempt.transport->Reconnect()) {
- D("attempting to reconnect %s failed.", attempt.transport->serial);
+ D("attempting to reconnect %s failed.", attempt.transport->serial.c_str());
if (attempt.attempts_left == 0) {
D("transport %s exceeded the number of retry attempts. giving up on it.",
- attempt.transport->serial);
+ attempt.transport->serial.c_str());
remove_transport(attempt.transport);
continue;
}
@@ -197,7 +197,7 @@ void ReconnectHandler::Run() {
continue;
}
- D("reconnection to %s succeeded.", attempt.transport->serial);
+ D("reconnection to %s succeeded.", attempt.transport->serial.c_str());
register_transport(attempt.transport);
}
}
@@ -402,14 +402,14 @@ void send_packet(apacket* p, atransport* t) {
p->msg.data_check = calculate_apacket_checksum(p);
}
- VLOG(TRANSPORT) << dump_packet(t->serial, "to remote", p);
+ VLOG(TRANSPORT) << dump_packet(t->serial.c_str(), "to remote", p);
if (t == nullptr) {
fatal("Transport is null");
}
if (t->Write(p) != 0) {
- D("%s: failed to enqueue packet, closing transport", t->serial);
+ D("%s: failed to enqueue packet, closing transport", t->serial.c_str());
t->Kick();
}
}
@@ -619,19 +619,13 @@ static void transport_registration_func(int _fd, unsigned ev, void*) {
t = m.transport;
if (m.action == 0) {
- D("transport: %s deleting", t->serial);
+ D("transport: %s deleting", t->serial.c_str());
{
std::lock_guard<std::recursive_mutex> lock(transport_lock);
transport_list.remove(t);
}
- if (t->product) free(t->product);
- if (t->serial) free(t->serial);
- if (t->model) free(t->model);
- if (t->device) free(t->device);
- if (t->devpath) free(t->devpath);
-
delete t;
update_transports();
@@ -646,11 +640,11 @@ static void transport_registration_func(int _fd, unsigned ev, void*) {
t->connection()->SetTransportName(t->serial_name());
t->connection()->SetReadCallback([t](Connection*, std::unique_ptr<apacket> p) {
if (!check_header(p.get(), t)) {
- D("%s: remote read: bad header", t->serial);
+ D("%s: remote read: bad header", t->serial.c_str());
return false;
}
- VLOG(TRANSPORT) << dump_packet(t->serial, "from remote", p.get());
+ VLOG(TRANSPORT) << dump_packet(t->serial.c_str(), "from remote", p.get());
apacket* packet = p.release();
// TODO: Does this need to run on the main thread?
@@ -658,7 +652,7 @@ static void transport_registration_func(int _fd, unsigned ev, void*) {
return true;
});
t->connection()->SetErrorCallback([t](Connection*, const std::string& error) {
- D("%s: connection terminated: %s", t->serial, error.c_str());
+ D("%s: connection terminated: %s", t->serial.c_str(), error.c_str());
fdevent_run_on_main_thread([t]() {
handle_offline(t);
transport_unref(t);
@@ -717,7 +711,7 @@ static void register_transport(atransport* transport) {
tmsg m;
m.transport = transport;
m.action = 1;
- D("transport: %s registered", transport->serial);
+ D("transport: %s registered", transport->serial.c_str());
if (transport_write_action(transport_registration_send, &m)) {
fatal_errno("cannot write transport registration socket\n");
}
@@ -727,7 +721,7 @@ static void remove_transport(atransport* transport) {
tmsg m;
m.transport = transport;
m.action = 0;
- D("transport: %s removed", transport->serial);
+ D("transport: %s removed", transport->serial.c_str());
if (transport_write_action(transport_registration_send, &m)) {
fatal_errno("cannot write transport registration socket\n");
}
@@ -743,38 +737,38 @@ static void transport_unref(atransport* t) {
if (t->ref_count == 0) {
t->connection()->Stop();
if (t->IsTcpDevice() && !t->kicked()) {
- D("transport: %s unref (attempting reconnection) %d", t->serial, t->kicked());
+ D("transport: %s unref (attempting reconnection) %d", t->serial.c_str(), t->kicked());
reconnect_handler.TrackTransport(t);
} else {
- D("transport: %s unref (kicking and closing)", t->serial);
+ D("transport: %s unref (kicking and closing)", t->serial.c_str());
remove_transport(t);
}
} else {
- D("transport: %s unref (count=%zu)", t->serial, t->ref_count);
+ D("transport: %s unref (count=%zu)", t->serial.c_str(), t->ref_count);
}
}
-static int qual_match(const char* to_test, const char* prefix, const char* qual,
+static int qual_match(const std::string& to_test, const char* prefix, const std::string& qual,
bool sanitize_qual) {
- if (!to_test || !*to_test) /* Return true if both the qual and to_test are null strings. */
- return !qual || !*qual;
+ if (to_test.empty()) /* Return true if both the qual and to_test are empty strings. */
+ return qual.empty();
- if (!qual) return 0;
+ if (qual.empty()) return 0;
+ const char* ptr = to_test.c_str();
if (prefix) {
while (*prefix) {
- if (*prefix++ != *to_test++) return 0;
+ if (*prefix++ != *ptr++) return 0;
}
}
- while (*qual) {
- char ch = *qual++;
+ for (char ch : qual) {
if (sanitize_qual && !isalnum(ch)) ch = '_';
- if (ch != *to_test++) return 0;
+ if (ch != *ptr++) return 0;
}
- /* Everything matched so far. Return true if *to_test is a NUL. */
- return !*to_test;
+ /* Everything matched so far. Return true if *ptr is a NUL. */
+ return !*ptr;
}
atransport* acquire_one_transport(TransportType type, const char* serial, TransportId transport_id,
@@ -921,7 +915,7 @@ int atransport::Write(apacket* p) {
void atransport::Kick() {
if (!kicked_.exchange(true)) {
- D("kicking transport %p %s", this, this->serial);
+ D("kicking transport %p %s", this, this->serial.c_str());
this->connection()->Stop();
}
}
@@ -1040,7 +1034,7 @@ void atransport::RunDisconnects() {
}
bool atransport::MatchesTarget(const std::string& target) const {
- if (serial) {
+ if (!serial.empty()) {
if (target == serial) {
return true;
} else if (type == kTransportLocal) {
@@ -1069,10 +1063,9 @@ bool atransport::MatchesTarget(const std::string& target) const {
}
}
- return (devpath && target == devpath) ||
- qual_match(target.c_str(), "product:", product, false) ||
- qual_match(target.c_str(), "model:", model, true) ||
- qual_match(target.c_str(), "device:", device, false);
+ return (target == devpath) || qual_match(target, "product:", product, false) ||
+ qual_match(target, "model:", model, true) ||
+ qual_match(target, "device:", device, false);
}
void atransport::SetConnectionEstablished(bool success) {
@@ -1093,9 +1086,9 @@ static std::string sanitize(std::string str, bool alphanumeric) {
return str;
}
-static void append_transport_info(std::string* result, const char* key, const char* value,
+static void append_transport_info(std::string* result, const char* key, const std::string& value,
bool alphanumeric) {
- if (value == nullptr || *value == '\0') {
+ if (value.empty()) {
return;
}
@@ -1105,8 +1098,8 @@ static void append_transport_info(std::string* result, const char* key, const ch
}
static void append_transport(const atransport* t, std::string* result, bool long_listing) {
- const char* serial = t->serial;
- if (!serial || !serial[0]) {
+ std::string serial = t->serial;
+ if (serial.empty()) {
serial = "(no serial number)";
}
@@ -1115,7 +1108,8 @@ static void append_transport(const atransport* t, std::string* result, bool long
*result += '\t';
*result += t->connection_state_name();
} else {
- android::base::StringAppendF(result, "%-22s %s", serial, t->connection_state_name().c_str());
+ android::base::StringAppendF(result, "%-22s %s", serial.c_str(),
+ t->connection_state_name().c_str());
append_transport_info(result, "", t->devpath, false);
append_transport_info(result, "product:", t->product, false);
@@ -1138,7 +1132,7 @@ std::string list_transports(bool long_listing) {
if (x->type != y->type) {
return x->type < y->type;
}
- return strcmp(x->serial, y->serial) < 0;
+ return x->serial < y->serial;
});
std::string result;
@@ -1181,7 +1175,7 @@ int register_socket_transport(int s, const char* serial, int port, int local,
std::unique_lock<std::recursive_mutex> lock(transport_lock);
for (const auto& transport : pending_list) {
- if (transport->serial && strcmp(serial, transport->serial) == 0) {
+ if (strcmp(serial, transport->serial.c_str()) == 0) {
VLOG(TRANSPORT) << "socket transport " << transport->serial
<< " is already in pending_list and fails to register";
delete t;
@@ -1190,7 +1184,7 @@ int register_socket_transport(int s, const char* serial, int port, int local,
}
for (const auto& transport : transport_list) {
- if (transport->serial && strcmp(serial, transport->serial) == 0) {
+ if (strcmp(serial, transport->serial.c_str()) == 0) {
VLOG(TRANSPORT) << "socket transport " << transport->serial
<< " is already in transport_list and fails to register";
delete t;
@@ -1199,7 +1193,7 @@ int register_socket_transport(int s, const char* serial, int port, int local,
}
pending_list.push_front(t);
- t->serial = strdup(serial);
+ t->serial = serial;
lock.unlock();
@@ -1220,7 +1214,7 @@ atransport* find_transport(const char* serial) {
std::lock_guard<std::recursive_mutex> lock(transport_lock);
for (auto& t : transport_list) {
- if (t->serial && strcmp(serial, t->serial) == 0) {
+ if (strcmp(serial, t->serial.c_str()) == 0) {
result = t;
break;
}
@@ -1251,11 +1245,11 @@ void register_usb_transport(usb_handle* usb, const char* serial, const char* dev
D("transport: %p init'ing for usb_handle %p (sn='%s')", t, usb, serial ? serial : "");
init_usb_transport(t, usb);
if (serial) {
- t->serial = strdup(serial);
+ t->serial = serial;
}
if (devpath) {
- t->devpath = strdup(devpath);
+ t->devpath = devpath;
}
{
diff --git a/adb/transport.h b/adb/transport.h
index cb2061510..e9c9d3753 100644
--- a/adb/transport.h
+++ b/adb/transport.h
@@ -238,11 +238,11 @@ class atransport {
TransportType type = kTransportAny;
// Used to identify transports for clients.
- char* serial = nullptr;
- char* product = nullptr;
- char* model = nullptr;
- char* device = nullptr;
- char* devpath = nullptr;
+ std::string serial;
+ std::string product;
+ std::string model;
+ std::string device;
+ std::string devpath;
bool IsTcpDevice() const { return type == kTransportLocal; }
@@ -253,7 +253,7 @@ class atransport {
char token[TOKEN_SIZE] = {};
size_t failed_auth_attempts = 0;
- std::string serial_name() const { return serial ? serial : "<unknown>"; }
+ std::string serial_name() const { return !serial.empty() ? serial : "<unknown>"; }
std::string connection_state_name() const;
void update_version(int version, size_t payload);
diff --git a/adb/transport_test.cpp b/adb/transport_test.cpp
index d987d4fa5..8c628d802 100644
--- a/adb/transport_test.cpp
+++ b/adb/transport_test.cpp
@@ -86,9 +86,9 @@ TEST(transport, parse_banner_no_features) {
ASSERT_EQ(0U, t.features().size());
ASSERT_EQ(kCsHost, t.GetConnectionState());
- ASSERT_EQ(nullptr, t.product);
- ASSERT_EQ(nullptr, t.model);
- ASSERT_EQ(nullptr, t.device);
+ ASSERT_EQ(std::string(), t.product);
+ ASSERT_EQ(std::string(), t.model);
+ ASSERT_EQ(std::string(), t.device);
}
TEST(transport, parse_banner_product_features) {
diff --git a/adb/types.h b/adb/types.h
index c6b3f0703..a3e5d4842 100644
--- a/adb/types.h
+++ b/adb/types.h
@@ -18,6 +18,7 @@
#include <algorithm>
#include <deque>
+#include <memory>
#include <type_traits>
#include <utility>
#include <vector>
@@ -37,7 +38,7 @@ struct Block {
template <typename Iterator>
Block(Iterator begin, Iterator end) : Block(end - begin) {
- std::copy(begin, end, data_);
+ std::copy(begin, end, data_.get());
}
Block(const Block& copy) = delete;
@@ -73,11 +74,11 @@ struct Block {
void assign(InputIt begin, InputIt end) {
clear();
allocate(end - begin);
- std::copy(begin, end, data_);
+ std::copy(begin, end, data_.get());
}
void clear() {
- free(data_);
+ data_.reset();
capacity_ = 0;
size_ = 0;
}
@@ -86,11 +87,11 @@ struct Block {
size_t size() const { return size_; }
bool empty() const { return size() == 0; }
- char* data() { return data_; }
- const char* data() const { return data_; }
+ char* data() { return data_.get(); }
+ const char* data() const { return data_.get(); }
- char* begin() { return data_; }
- const char* begin() const { return data_; }
+ char* begin() { return data_.get(); }
+ const char* begin() const { return data_.get(); }
char* end() { return data() + size_; }
const char* end() const { return data() + size_; }
@@ -108,13 +109,13 @@ struct Block {
CHECK_EQ(0ULL, capacity_);
CHECK_EQ(0ULL, size_);
if (size != 0) {
- data_ = static_cast<char*>(malloc(size));
+ data_ = std::make_unique<char[]>(size);
capacity_ = size;
size_ = size;
}
}
- char* data_ = nullptr;
+ std::unique_ptr<char[]> data_;
size_t capacity_ = 0;
size_t size_ = 0;
};