Merge changes I1d899134,If4ea92ae,I92c05721,I298517b6,Iccbeb619, ... am: d5db4e1b97
am: 2e6c35dbba
Change-Id: I78ad5fc2c177496832dde436bd2f565d4a28f8ac
diff --git a/adb/adb.cpp b/adb/adb.cpp
index 9c0eeca..fdf720c 100644
--- a/adb/adb.cpp
+++ b/adb/adb.cpp
@@ -357,9 +357,9 @@
case A_OPEN: /* OPEN(local-id, 0, "destination") */
if (t->online && p->msg.arg0 != 0 && p->msg.arg1 == 0) {
- // TODO: Switch to string_view.
- std::string address(p->payload.begin(), p->payload.end());
- asocket* s = create_local_service_socket(address.c_str(), t);
+ std::string_view address(p->payload.begin(), p->payload.size());
+
+ asocket* s = create_local_service_socket(address, t);
if (s == nullptr) {
send_close(0, p->msg.arg0, t);
} else {
@@ -600,7 +600,7 @@
fprintf(stderr, "Full server startup log: %s\n", GetLogFilePath().c_str());
fprintf(stderr, "Server had pid: %d\n", pid);
- android::base::unique_fd fd(unix_open(GetLogFilePath().c_str(), O_RDONLY));
+ android::base::unique_fd fd(unix_open(GetLogFilePath(), O_RDONLY));
if (fd == -1) return;
// Let's not show more than 128KiB of log...
diff --git a/adb/adb.h b/adb/adb.h
index cdd6346..47ea0e8 100644
--- a/adb/adb.h
+++ b/adb/adb.h
@@ -139,9 +139,9 @@
atransport* find_emulator_transport_by_console_port(int console_port);
#endif
-int service_to_fd(const char* name, atransport* transport);
+int service_to_fd(std::string_view name, atransport* transport);
#if !ADB_HOST
-unique_fd daemon_service_to_fd(const char* name, atransport* transport);
+unique_fd daemon_service_to_fd(std::string_view name, atransport* transport);
#endif
#if ADB_HOST
diff --git a/adb/adb_trace.cpp b/adb/adb_trace.cpp
index a024a89..2bd6a3e 100644
--- a/adb/adb_trace.cpp
+++ b/adb/adb_trace.cpp
@@ -72,8 +72,7 @@
}
void start_device_log(void) {
- int fd = unix_open(get_log_file_name().c_str(),
- O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC, 0640);
+ int fd = unix_open(get_log_file_name(), O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC, 0640);
if (fd == -1) {
return;
}
diff --git a/adb/adb_utils.h b/adb/adb_utils.h
index 6d12225..8253487 100644
--- a/adb/adb_utils.h
+++ b/adb/adb_utils.h
@@ -19,6 +19,8 @@
#include <condition_variable>
#include <mutex>
#include <string>
+#include <string_view>
+#include <type_traits>
#include <vector>
#include <android-base/macros.h>
@@ -94,3 +96,47 @@
};
std::string GetLogFilePath();
+
+inline std::string_view StripTrailingNulls(std::string_view str) {
+ size_t n = 0;
+ for (auto it = str.rbegin(); it != str.rend(); ++it) {
+ if (*it != '\0') {
+ break;
+ }
+ ++n;
+ }
+
+ str.remove_suffix(n);
+ return str;
+}
+
+// Base-10 stroll on a string_view.
+template <typename T>
+inline bool ParseUint(T* result, std::string_view str, std::string_view* remaining) {
+ if (str.empty() || !isdigit(str[0])) {
+ return false;
+ }
+
+ T value = 0;
+ std::string_view::iterator it;
+ constexpr T max = std::numeric_limits<T>::max();
+ for (it = str.begin(); it != str.end() && isdigit(*it); ++it) {
+ if (value > max / 10) {
+ return false;
+ }
+
+ value *= 10;
+
+ T digit = *it - '0';
+ if (value > max - digit) {
+ return false;
+ }
+
+ value += digit;
+ }
+ *result = value;
+ if (remaining) {
+ *remaining = str.substr(it - str.begin());
+ }
+ return true;
+}
diff --git a/adb/adb_utils_test.cpp b/adb/adb_utils_test.cpp
index 870f6f0..bb09425 100644
--- a/adb/adb_utils_test.cpp
+++ b/adb/adb_utils_test.cpp
@@ -181,3 +181,48 @@
EXPECT_FALSE(forward_targets_are_valid("tcp:8000", "tcp:a", &error));
EXPECT_FALSE(forward_targets_are_valid("tcp:8000", "tcp:22x", &error));
}
+
+void TestParseUint(std::string_view string, bool expected_success, uint32_t expected_value = 0) {
+ // Standalone.
+ {
+ uint32_t value;
+ std::string_view remaining;
+ bool success = ParseUint(&value, string, &remaining);
+ EXPECT_EQ(success, expected_success);
+ if (expected_success) {
+ EXPECT_EQ(value, expected_value);
+ }
+ EXPECT_TRUE(remaining.empty());
+ }
+
+ // With trailing text.
+ {
+ std::string text = std::string(string) + "foo";
+ uint32_t value;
+ std::string_view remaining;
+ bool success = ParseUint(&value, text, &remaining);
+ EXPECT_EQ(success, expected_success);
+ if (expected_success) {
+ EXPECT_EQ(value, expected_value);
+ EXPECT_EQ(remaining, "foo");
+ }
+ }
+}
+
+TEST(adb_utils, ParseUint) {
+ TestParseUint("", false);
+ TestParseUint("foo", false);
+ TestParseUint("foo123", false);
+ TestParseUint("-1", false);
+
+ TestParseUint("123", true, 123);
+ TestParseUint("9999999999999999999999999", false);
+ TestParseUint(std::to_string(UINT32_MAX), true, UINT32_MAX);
+ TestParseUint("0" + std::to_string(UINT32_MAX), true, UINT32_MAX);
+ TestParseUint(std::to_string(static_cast<uint64_t>(UINT32_MAX) + 1), false);
+ TestParseUint("0" + std::to_string(static_cast<uint64_t>(UINT32_MAX) + 1), false);
+
+ std::string x = std::to_string(UINT32_MAX) + "123";
+ std::string_view substr = std::string_view(x).substr(0, std::to_string(UINT32_MAX).size());
+ TestParseUint(substr, true, UINT32_MAX);
+}
diff --git a/adb/client/main.cpp b/adb/client/main.cpp
index fb581a6..2ee81a9 100644
--- a/adb/client/main.cpp
+++ b/adb/client/main.cpp
@@ -40,7 +40,7 @@
static void setup_daemon_logging() {
const std::string log_file_path(GetLogFilePath());
- int fd = unix_open(log_file_path.c_str(), O_WRONLY | O_CREAT | O_APPEND, 0640);
+ int fd = unix_open(log_file_path, O_WRONLY | O_CREAT | O_APPEND, 0640);
if (fd == -1) {
PLOG(FATAL) << "cannot open " << log_file_path;
}
diff --git a/adb/client/usb_linux.cpp b/adb/client/usb_linux.cpp
index f1bf559..1168958 100644
--- a/adb/client/usb_linux.cpp
+++ b/adb/client/usb_linux.cpp
@@ -39,6 +39,7 @@
#include <list>
#include <mutex>
#include <string>
+#include <string_view>
#include <thread>
#include <android-base/file.h>
@@ -90,7 +91,7 @@
static auto& g_usb_handles_mutex = *new std::mutex();
static auto& g_usb_handles = *new std::list<usb_handle*>();
-static int is_known_device(const char* dev_name) {
+static int is_known_device(std::string_view dev_name) {
std::lock_guard<std::mutex> lock(g_usb_handles_mutex);
for (usb_handle* usb : g_usb_handles) {
if (usb->path == dev_name) {
@@ -152,11 +153,11 @@
if (contains_non_digit(de->d_name)) continue;
std::string dev_name = bus_name + "/" + de->d_name;
- if (is_known_device(dev_name.c_str())) {
+ if (is_known_device(dev_name)) {
continue;
}
- int fd = unix_open(dev_name.c_str(), O_RDONLY | O_CLOEXEC);
+ int fd = unix_open(dev_name, O_RDONLY | O_CLOEXEC);
if (fd == -1) {
continue;
}
@@ -535,10 +536,10 @@
// Initialize mark so we don't get garbage collected after the device scan.
usb->mark = true;
- usb->fd = unix_open(usb->path.c_str(), O_RDWR | O_CLOEXEC);
+ usb->fd = unix_open(usb->path, O_RDWR | O_CLOEXEC);
if (usb->fd == -1) {
// Opening RW failed, so see if we have RO access.
- usb->fd = unix_open(usb->path.c_str(), O_RDONLY | O_CLOEXEC);
+ usb->fd = unix_open(usb->path, O_RDONLY | O_CLOEXEC);
if (usb->fd == -1) {
D("[ usb open %s failed: %s]", usb->path.c_str(), strerror(errno));
return;
diff --git a/adb/daemon/remount_service.cpp b/adb/daemon/remount_service.cpp
index 1a92317..80b3e06 100644
--- a/adb/daemon/remount_service.cpp
+++ b/adb/daemon/remount_service.cpp
@@ -103,7 +103,7 @@
bool make_block_device_writable(const std::string& dev) {
if (dev_is_overlayfs(dev)) return true;
- int fd = unix_open(dev.c_str(), O_RDONLY | O_CLOEXEC);
+ int fd = unix_open(dev, O_RDONLY | O_CLOEXEC);
if (fd == -1) {
return false;
}
diff --git a/adb/daemon/services.cpp b/adb/daemon/services.cpp
index 3182ddd..84a7655 100644
--- a/adb/daemon/services.cpp
+++ b/adb/daemon/services.cpp
@@ -151,14 +151,17 @@
kick_transport(t);
}
-unique_fd reverse_service(const char* command, atransport* transport) {
+unique_fd reverse_service(std::string_view command, atransport* transport) {
+ // TODO: Switch handle_forward_request to std::string_view.
+ std::string str(command);
+
int s[2];
if (adb_socketpair(s)) {
PLOG(ERROR) << "cannot create service socket pair.";
return unique_fd{};
}
VLOG(SERVICES) << "service socketpair: " << s[0] << ", " << s[1];
- if (!handle_forward_request(command, transport, s[1])) {
+ if (!handle_forward_request(str.c_str(), transport, s[1])) {
SendFail(s[1], "not a reverse forwarding command");
}
adb_close(s[1]);
@@ -167,15 +170,16 @@
// Shell service string can look like:
// shell[,arg1,arg2,...]:[command]
-unique_fd ShellService(const std::string& args, const atransport* transport) {
+unique_fd ShellService(std::string_view 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;
return unique_fd{};
}
- const std::string service_args = args.substr(0, delimiter_index);
- const std::string command = args.substr(delimiter_index + 1);
+ // TODO: android::base::Split(const std::string_view&, ...)
+ std::string service_args(args.substr(0, delimiter_index));
+ std::string command(args.substr(delimiter_index + 1));
// Defaults:
// PTY for interactive, raw for non-interactive.
@@ -192,15 +196,15 @@
type = SubprocessType::kPty;
} else if (arg == kShellServiceArgShellProtocol) {
protocol = SubprocessProtocol::kShell;
- } else if (android::base::StartsWith(arg, "TERM=")) {
- terminal_type = arg.substr(5);
+ } else if (arg.starts_with("TERM=")) {
+ terminal_type = arg.substr(strlen("TERM="));
} else if (!arg.empty()) {
// This is not an error to allow for future expansion.
LOG(WARNING) << "Ignoring unknown shell service argument: " << arg;
}
}
- return StartSubprocess(command.c_str(), terminal_type.c_str(), type, protocol);
+ return StartSubprocess(command, terminal_type.c_str(), type, protocol);
}
static void spin_service(unique_fd fd) {
@@ -323,59 +327,77 @@
return nullptr;
}
-unique_fd daemon_service_to_fd(const char* name, atransport* transport) {
- if (!strncmp("dev:", name, 4)) {
- return unique_fd{unix_open(name + 4, O_RDWR | O_CLOEXEC)};
- } else if (!strncmp(name, "framebuffer:", 12)) {
+unique_fd daemon_service_to_fd(std::string_view name, atransport* transport) {
+ // Historically, we received service names as a char*, and stopped at the first NUL byte.
+ // The client unintentionally sent strings with embedded NULs, which post-string_view, start
+ // being interpreted as part of the string, unless we explicitly strip them.
+ // Notably, shell checks that the part after "shell:" is empty to determine whether the session
+ // is interactive, and {'\0'} is non-empty.
+ name = StripTrailingNulls(name);
+
+ if (name.starts_with("dev:")) {
+ name.remove_prefix(strlen("dev:"));
+ return unique_fd{unix_open(name, O_RDWR | O_CLOEXEC)};
+ } else if (name.starts_with("framebuffer:")) {
return create_service_thread("fb", framebuffer_service);
- } else if (!strncmp(name, "jdwp:", 5)) {
- return create_jdwp_connection_fd(atoi(name + 5));
- } else if (!strncmp(name, "shell", 5)) {
- return ShellService(name + 5, transport);
- } else if (!strncmp(name, "exec:", 5)) {
- return StartSubprocess(name + 5, nullptr, SubprocessType::kRaw, SubprocessProtocol::kNone);
- } else if (!strncmp(name, "sync:", 5)) {
+ } else if (name.starts_with("jdwp:")) {
+ name.remove_prefix(strlen("jdwp:"));
+ std::string str(name);
+ return create_jdwp_connection_fd(atoi(str.c_str()));
+ } else if (name.starts_with("shell")) {
+ name.remove_prefix(strlen("shell"));
+ return ShellService(name, transport);
+ } else if (name.starts_with("exec:")) {
+ name.remove_prefix(strlen("exec:"));
+ return StartSubprocess(std::string(name), nullptr, SubprocessType::kRaw,
+ SubprocessProtocol::kNone);
+ } else if (name.starts_with("sync:")) {
return create_service_thread("sync", file_sync_service);
- } else if (!strncmp(name, "remount:", 8)) {
- std::string options(name + strlen("remount:"));
+ } else if (name.starts_with("remount:")) {
+ std::string arg(name.begin() + strlen("remount:"), name.end());
return create_service_thread("remount",
- std::bind(remount_service, std::placeholders::_1, options));
- } else if (!strncmp(name, "reboot:", 7)) {
- std::string arg(name + strlen("reboot:"));
+ std::bind(remount_service, std::placeholders::_1, arg));
+ } else if (name.starts_with("reboot:")) {
+ std::string arg(name.begin() + strlen("reboot:"), name.end());
return create_service_thread("reboot",
std::bind(reboot_service, std::placeholders::_1, arg));
- } else if (!strncmp(name, "root:", 5)) {
+ } else if (name.starts_with("root:")) {
return create_service_thread("root", restart_root_service);
- } else if (!strncmp(name, "unroot:", 7)) {
+ } else if (name.starts_with("unroot:")) {
return create_service_thread("unroot", restart_unroot_service);
- } else if (!strncmp(name, "backup:", 7)) {
- return 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 (name.starts_with("backup:")) {
+ name.remove_prefix(strlen("backup:"));
+ std::string cmd = "/system/bin/bu backup ";
+ cmd += name;
+ return StartSubprocess(cmd, nullptr, SubprocessType::kRaw, SubprocessProtocol::kNone);
+ } else if (name.starts_with("restore:")) {
return StartSubprocess("/system/bin/bu restore", nullptr, SubprocessType::kRaw,
SubprocessProtocol::kNone);
- } else if (!strncmp(name, "tcpip:", 6)) {
+ } else if (name.starts_with("tcpip:")) {
+ name.remove_prefix(strlen("tcpip:"));
+ std::string str(name);
+
int port;
- if (sscanf(name + 6, "%d", &port) != 1) {
+ if (sscanf(str.c_str(), "%d", &port) != 1) {
return unique_fd{};
}
return create_service_thread("tcp",
std::bind(restart_tcp_service, std::placeholders::_1, port));
- } else if (!strncmp(name, "usb:", 4)) {
+ } else if (name.starts_with("usb:")) {
return create_service_thread("usb", restart_usb_service);
- } else if (!strncmp(name, "reverse:", 8)) {
- return reverse_service(name + 8, transport);
- } else if (!strncmp(name, "disable-verity:", 15)) {
+ } else if (name.starts_with("reverse:")) {
+ name.remove_prefix(strlen("reverse:"));
+ return reverse_service(name, transport);
+ } else if (name.starts_with("disable-verity:")) {
return create_service_thread("verity-on", std::bind(set_verity_enabled_state_service,
std::placeholders::_1, false));
- } else if (!strncmp(name, "enable-verity:", 15)) {
+ } else if (name.starts_with("enable-verity:")) {
return create_service_thread("verity-off", std::bind(set_verity_enabled_state_service,
std::placeholders::_1, true));
- } else if (!strcmp(name, "reconnect")) {
+ } else if (name == "reconnect") {
return create_service_thread(
"reconnect", std::bind(reconnect_service, std::placeholders::_1, transport));
- } else if (!strcmp(name, "spin")) {
+ } else if (name == "spin") {
return create_service_thread("spin", spin_service);
}
diff --git a/adb/daemon/shell_service.cpp b/adb/daemon/shell_service.cpp
index 8805fc1..595d5c6 100644
--- a/adb/daemon/shell_service.cpp
+++ b/adb/daemon/shell_service.cpp
@@ -140,8 +140,8 @@
class Subprocess {
public:
- Subprocess(const std::string& command, const char* terminal_type,
- SubprocessType type, SubprocessProtocol protocol);
+ Subprocess(std::string command, const char* terminal_type, SubprocessType type,
+ SubprocessProtocol protocol);
~Subprocess();
const std::string& command() const { return command_; }
@@ -191,9 +191,9 @@
DISALLOW_COPY_AND_ASSIGN(Subprocess);
};
-Subprocess::Subprocess(const std::string& command, const char* terminal_type,
- SubprocessType type, SubprocessProtocol protocol)
- : command_(command),
+Subprocess::Subprocess(std::string command, const char* terminal_type, SubprocessType type,
+ SubprocessProtocol protocol)
+ : command_(std::move(command)),
terminal_type_(terminal_type ? terminal_type : ""),
type_(type),
protocol_(protocol) {
@@ -745,14 +745,13 @@
return read;
}
-unique_fd StartSubprocess(const char* name, const char* terminal_type, SubprocessType type,
+unique_fd StartSubprocess(std::string name, const char* terminal_type, SubprocessType type,
SubprocessProtocol protocol) {
D("starting %s subprocess (protocol=%s, TERM=%s): '%s'",
type == SubprocessType::kRaw ? "raw" : "PTY",
- protocol == SubprocessProtocol::kNone ? "none" : "shell",
- terminal_type, name);
+ protocol == SubprocessProtocol::kNone ? "none" : "shell", terminal_type, name.c_str());
- auto subprocess = std::make_unique<Subprocess>(name, terminal_type, type, protocol);
+ auto subprocess = std::make_unique<Subprocess>(std::move(name), terminal_type, type, protocol);
if (!subprocess) {
LOG(ERROR) << "failed to allocate new subprocess";
return ReportError(protocol, "failed to allocate new subprocess");
diff --git a/adb/daemon/shell_service.h b/adb/daemon/shell_service.h
index 2a48923..421d61f 100644
--- a/adb/daemon/shell_service.h
+++ b/adb/daemon/shell_service.h
@@ -16,6 +16,8 @@
#pragma once
+#include <string>
+
#include "adb_unique_fd.h"
enum class SubprocessType {
@@ -32,5 +34,5 @@
// shell is started, otherwise |name| is executed non-interactively.
//
// Returns an open FD connected to the subprocess or -1 on failure.
-unique_fd StartSubprocess(const char* name, const char* terminal_type, SubprocessType type,
+unique_fd StartSubprocess(std::string name, const char* terminal_type, SubprocessType type,
SubprocessProtocol protocol);
diff --git a/adb/services.cpp b/adb/services.cpp
index 4b033bd..8636657 100644
--- a/adb/services.cpp
+++ b/adb/services.cpp
@@ -71,7 +71,7 @@
return unique_fd(s[0]);
}
-int service_to_fd(const char* name, atransport* transport) {
+int service_to_fd(std::string_view name, atransport* transport) {
int ret = -1;
if (is_socket_spec(name)) {
diff --git a/adb/socket.h b/adb/socket.h
index 0905aab..f9ad4f8 100644
--- a/adb/socket.h
+++ b/adb/socket.h
@@ -103,7 +103,7 @@
void close_all_sockets(atransport *t);
asocket *create_local_socket(int fd);
-asocket* create_local_service_socket(const char* destination, atransport* transport);
+asocket* create_local_service_socket(std::string_view destination, atransport* transport);
asocket *create_remote_socket(unsigned id, atransport *t);
void connect_to_remote(asocket *s, const char *destination);
diff --git a/adb/socket_spec.cpp b/adb/socket_spec.cpp
index eb4df97..4cddc84 100644
--- a/adb/socket_spec.cpp
+++ b/adb/socket_spec.cpp
@@ -17,6 +17,7 @@
#include "socket_spec.h"
#include <string>
+#include <string_view>
#include <unordered_map>
#include <vector>
@@ -29,7 +30,8 @@
#include "adb.h"
#include "sysdeps.h"
-using android::base::StartsWith;
+using namespace std::string_literals;
+
using android::base::StringPrintf;
#if defined(__linux__)
@@ -64,10 +66,11 @@
{ "localfilesystem", { ANDROID_SOCKET_NAMESPACE_FILESYSTEM, !ADB_WINDOWS } },
});
-bool parse_tcp_socket_spec(const std::string& spec, std::string* hostname, int* port,
+bool parse_tcp_socket_spec(std::string_view spec, std::string* hostname, int* port,
std::string* error) {
- if (!StartsWith(spec, "tcp:")) {
- *error = StringPrintf("specification is not tcp: '%s'", spec.c_str());
+ if (!spec.starts_with("tcp:")) {
+ *error = "specification is not tcp: ";
+ *error += spec;
return false;
}
@@ -84,7 +87,7 @@
return false;
}
} else {
- std::string addr = spec.substr(4);
+ std::string addr(spec.substr(4));
port_value = -1;
// FIXME: ParseNetAddress rejects port 0. This currently doesn't hurt, because listening
@@ -94,7 +97,8 @@
}
if (port_value == -1) {
- *error = StringPrintf("missing port in specification: '%s'", spec.c_str());
+ *error = "missing port in specification: ";
+ *error += spec;
return false;
}
}
@@ -110,25 +114,25 @@
return true;
}
-static bool tcp_host_is_local(const std::string& hostname) {
+static bool tcp_host_is_local(std::string_view hostname) {
// FIXME
return hostname.empty() || hostname == "localhost";
}
-bool is_socket_spec(const std::string& spec) {
+bool is_socket_spec(std::string_view spec) {
for (const auto& it : kLocalSocketTypes) {
std::string prefix = it.first + ":";
- if (StartsWith(spec, prefix)) {
+ if (spec.starts_with(prefix)) {
return true;
}
}
- return StartsWith(spec, "tcp:");
+ return spec.starts_with("tcp:");
}
-bool is_local_socket_spec(const std::string& spec) {
+bool is_local_socket_spec(std::string_view spec) {
for (const auto& it : kLocalSocketTypes) {
std::string prefix = it.first + ":";
- if (StartsWith(spec, prefix)) {
+ if (spec.starts_with(prefix)) {
return true;
}
}
@@ -141,8 +145,8 @@
return tcp_host_is_local(hostname);
}
-int socket_spec_connect(const std::string& spec, std::string* error) {
- if (StartsWith(spec, "tcp:")) {
+int socket_spec_connect(std::string_view spec, std::string* error) {
+ if (spec.starts_with("tcp:")) {
std::string hostname;
int port;
if (!parse_tcp_socket_spec(spec, &hostname, &port, error)) {
@@ -170,7 +174,7 @@
for (const auto& it : kLocalSocketTypes) {
std::string prefix = it.first + ":";
- if (StartsWith(spec, prefix)) {
+ if (spec.starts_with(prefix)) {
if (!it.second.available) {
*error = StringPrintf("socket type %s is unavailable on this platform",
it.first.c_str());
@@ -182,12 +186,13 @@
}
}
- *error = StringPrintf("unknown socket specification '%s'", spec.c_str());
+ *error = "unknown socket specification: ";
+ *error += spec;
return -1;
}
-int socket_spec_listen(const std::string& spec, std::string* error, int* resolved_tcp_port) {
- if (StartsWith(spec, "tcp:")) {
+int socket_spec_listen(std::string_view spec, std::string* error, int* resolved_tcp_port) {
+ if (spec.starts_with("tcp:")) {
std::string hostname;
int port;
if (!parse_tcp_socket_spec(spec, &hostname, &port, error)) {
@@ -213,10 +218,10 @@
for (const auto& it : kLocalSocketTypes) {
std::string prefix = it.first + ":";
- if (StartsWith(spec, prefix)) {
+ if (spec.starts_with(prefix)) {
if (!it.second.available) {
- *error = StringPrintf("attempted to listen on unavailable socket type: '%s'",
- spec.c_str());
+ *error = "attempted to listen on unavailable socket type: ";
+ *error += spec;
return -1;
}
@@ -225,6 +230,7 @@
}
}
- *error = StringPrintf("unknown socket specification '%s'", spec.c_str());
+ *error = "unknown socket specification:";
+ *error += spec;
return -1;
}
diff --git a/adb/socket_spec.h b/adb/socket_spec.h
index 6920e91..5b06973 100644
--- a/adb/socket_spec.h
+++ b/adb/socket_spec.h
@@ -19,13 +19,12 @@
#include <string>
// Returns true if the argument starts with a plausible socket prefix.
-bool is_socket_spec(const std::string& spec);
-bool is_local_socket_spec(const std::string& spec);
+bool is_socket_spec(std::string_view spec);
+bool is_local_socket_spec(std::string_view spec);
-int socket_spec_connect(const std::string& spec, std::string* error);
-int socket_spec_listen(const std::string& spec, std::string* error,
- int* resolved_tcp_port = nullptr);
+int socket_spec_connect(std::string_view spec, std::string* error);
+int socket_spec_listen(std::string_view spec, std::string* error, int* resolved_tcp_port = nullptr);
// Exposed for testing.
-bool parse_tcp_socket_spec(const std::string& spec, std::string* hostname, int* port,
+bool parse_tcp_socket_spec(std::string_view spec, std::string* hostname, int* port,
std::string* error);
diff --git a/adb/sockets.cpp b/adb/sockets.cpp
index 1bd57c1..cb8cd16 100644
--- a/adb/sockets.cpp
+++ b/adb/sockets.cpp
@@ -346,7 +346,7 @@
return s;
}
-asocket* create_local_service_socket(const char* name, atransport* transport) {
+asocket* create_local_service_socket(std::string_view name, atransport* transport) {
#if !ADB_HOST
if (asocket* s = daemon_service_to_socket(name); s) {
return s;
@@ -358,13 +358,12 @@
}
asocket* s = create_local_socket(fd);
- D("LS(%d): bound to '%s' via %d", s->id, name, fd);
+ LOG(VERBOSE) << "LS(" << s->id << "): bound to '" << name << "' via " << fd;
#if !ADB_HOST
- if ((!strncmp(name, "root:", 5) && getuid() != 0 && __android_log_is_debuggable()) ||
- (!strncmp(name, "unroot:", 7) && getuid() == 0) ||
- !strncmp(name, "usb:", 4) ||
- !strncmp(name, "tcpip:", 6)) {
+ if ((name.starts_with("root:") && getuid() != 0 && __android_log_is_debuggable()) ||
+ (name.starts_with("unroot:") && getuid() == 0) || name.starts_with("usb:") ||
+ name.starts_with("tcpip:")) {
D("LS(%d): enabling exit_on_close", s->id);
s->exit_on_close = 1;
}
diff --git a/adb/sysdeps.h b/adb/sysdeps.h
index b8d7e06..15247e7 100644
--- a/adb/sysdeps.h
+++ b/adb/sysdeps.h
@@ -27,6 +27,7 @@
#include <errno.h>
#include <string>
+#include <string_view>
#include <vector>
// Include this before open/close/unlink are defined as macros below.
@@ -139,7 +140,7 @@
}
// See the comments for the !defined(_WIN32) version of unix_open().
-extern int unix_open(const char* path, int options, ...);
+extern int unix_open(std::string_view path, int options, ...);
#define open ___xxx_unix_open
// Checks if |fd| corresponds to a console.
@@ -357,20 +358,17 @@
// by unix_read(), unix_write(), unix_close()). Also, the C Runtime has
// configurable CR/LF translation which defaults to text mode, but is settable
// with _setmode().
-static __inline__ int unix_open(const char* path, int options,...)
-{
- if ((options & O_CREAT) == 0)
- {
- return TEMP_FAILURE_RETRY( open(path, options) );
- }
- else
- {
- int mode;
- va_list args;
- va_start( args, options );
- mode = va_arg( args, int );
- va_end( args );
- return TEMP_FAILURE_RETRY( open( path, options, mode ) );
+static __inline__ int unix_open(std::string_view path, int options, ...) {
+ std::string zero_terminated(path.begin(), path.end());
+ if ((options & O_CREAT) == 0) {
+ return TEMP_FAILURE_RETRY(open(zero_terminated.c_str(), options));
+ } else {
+ int mode;
+ va_list args;
+ va_start(args, options);
+ mode = va_arg(args, int);
+ va_end(args);
+ return TEMP_FAILURE_RETRY(open(zero_terminated.c_str(), options, mode));
}
}
diff --git a/adb/sysdeps_win32.cpp b/adb/sysdeps_win32.cpp
index 8a6541d..dbc8920 100644
--- a/adb/sysdeps_win32.cpp
+++ b/adb/sysdeps_win32.cpp
@@ -29,6 +29,7 @@
#include <memory>
#include <mutex>
#include <string>
+#include <string_view>
#include <unordered_map>
#include <vector>
@@ -2203,15 +2204,15 @@
}
}
-int unix_open(const char* path, int options, ...) {
+int unix_open(std::string_view path, int options, ...) {
std::wstring path_wide;
- if (!android::base::UTF8ToWide(path, &path_wide)) {
+ if (!android::base::UTF8ToWide(path.data(), path.size(), &path_wide)) {
return -1;
}
if ((options & O_CREAT) == 0) {
return _wopen(path_wide.c_str(), options);
} else {
- int mode;
+ int mode;
va_list args;
va_start(args, options);
mode = va_arg(args, int);