summaryrefslogtreecommitdiffstats
path: root/adb/adb_client.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'adb/adb_client.cpp')
-rw-r--r--adb/adb_client.cpp193
1 files changed, 81 insertions, 112 deletions
diff --git a/adb/adb_client.cpp b/adb/adb_client.cpp
index 0b2d038..62f79fa 100644
--- a/adb/adb_client.cpp
+++ b/adb/adb_client.cpp
@@ -32,6 +32,7 @@
#include <vector>
#include <base/stringprintf.h>
+#include <base/strings.h>
#include "adb_io.h"
@@ -41,6 +42,29 @@ static const char* __adb_serial = NULL;
static int __adb_server_port = DEFAULT_ADB_PORT;
static const char* __adb_server_name = NULL;
+static std::string perror_str(const char* msg) {
+ return android::base::StringPrintf("%s: %s", msg, strerror(errno));
+}
+
+static bool ReadProtocolString(int fd, std::string* s, std::string* error) {
+ char buf[5];
+
+ if (!ReadFdExactly(fd, buf, 4)) {
+ *error = perror_str("protocol fault (couldn't read status length)");
+ return false;
+ }
+ buf[4] = 0;
+
+ unsigned long len = strtoul(buf, 0, 16);
+ s->resize(len + 1, '\0'); // Ensure NUL-termination.
+ if (!ReadFdExactly(fd, &(*s)[0], len)) {
+ *error = perror_str("protocol fault (couldn't read status message)");
+ return false;
+ }
+
+ return true;
+}
+
void adb_set_transport(transport_type type, const char* serial)
{
__adb_transport = type;
@@ -57,58 +81,36 @@ void adb_set_tcp_name(const char* hostname)
__adb_server_name = hostname;
}
-int adb_get_emulator_console_port(void)
-{
- const char* serial = __adb_serial;
- int port;
-
- if (serial == NULL) {
- /* if no specific device was specified, we need to look at */
- /* the list of connected devices, and extract an emulator */
- /* name from it. two emulators is an error */
- std::string error;
- char* tmp = adb_query("host:devices", &error);
- char* p = tmp;
- if (!tmp) {
- printf("no emulator connected: %s\n", error.c_str());
- return -1;
- }
- while (*p) {
- char* q = strchr(p, '\n');
- if (q != NULL)
- *q++ = 0;
- else
- q = p + strlen(p);
-
- if (!memcmp(p, LOCAL_CLIENT_PREFIX, sizeof(LOCAL_CLIENT_PREFIX)-1)) {
- if (serial != NULL) { /* more than one emulator listed */
- free(tmp);
- return -2;
- }
- serial = p;
- }
-
- p = q;
- }
- free(tmp);
-
- if (serial == NULL)
- return -1; /* no emulator found */
+int adb_get_emulator_console_port() {
+ if (__adb_serial) {
+ // The user specified a serial number; is it an emulator?
+ int port;
+ return (sscanf(__adb_serial, "emulator-%d", &port) == 1) ? port : -1;
}
- else {
- if (memcmp(serial, LOCAL_CLIENT_PREFIX, sizeof(LOCAL_CLIENT_PREFIX)-1) != 0)
- return -1; /* not an emulator */
+
+ // No specific device was given, so get the list of connected
+ // devices and search for emulators. If there's one, we'll
+ // take it. If there are more than one, that's an error.
+ std::string devices;
+ std::string error;
+ if (!adb_query("host:devices", &devices, &error)) {
+ printf("no emulator connected: %s\n", error.c_str());
+ return -1;
}
- serial += sizeof(LOCAL_CLIENT_PREFIX)-1;
- port = strtol(serial, NULL, 10);
+ int port;
+ size_t emulator_count = 0;
+ for (auto& device : android::base::Split(devices, "\n")) {
+ if (sscanf(device.c_str(), "emulator-%d", &port) == 1) {
+ if (++emulator_count > 1) {
+ return -2;
+ }
+ }
+ }
+ if (emulator_count == 0) return -1;
return port;
}
-std::string perror_str(const char* msg) {
- return android::base::StringPrintf("%s: %s", msg, strerror(errno));
-}
-
static int switch_socket_transport(int fd, std::string* error) {
std::string service;
if (__adb_serial) {
@@ -170,47 +172,36 @@ bool adb_status(int fd, std::string* error) {
return false;
}
- if (!ReadFdExactly(fd, buf, 4)) {
- *error = perror_str("protocol fault (couldn't read status length)");
- return false;
- }
- buf[4] = 0;
-
- unsigned long len = strtoul(buf, 0, 16);
- error->resize(len + 1, '\0'); // Ensure NUL-termination.
- if (!ReadFdExactly(fd, &(*error)[0], len)) {
- *error = perror_str("protocol fault (couldn't read status message)");
- }
+ ReadProtocolString(fd, error, error);
return false;
}
-int _adb_connect(const char *service, std::string* error) {
- char tmp[5];
- int fd;
-
- D("_adb_connect: %s\n", service);
- size_t len = strlen(service);
- if ((len < 1) || (len > 1024)) {
- *error = android::base::StringPrintf("service name too long (%d)", static_cast<int>(len));
+int _adb_connect(const std::string& service, std::string* error) {
+ D("_adb_connect: %s\n", service.c_str());
+ if (service.empty() || service.size() > 1024) {
+ *error = android::base::StringPrintf("bad service name length (%d)",
+ static_cast<int>(service.size()));
return -1;
}
- snprintf(tmp, sizeof tmp, "%04zx", len);
- if (__adb_server_name)
+ int fd;
+ if (__adb_server_name) {
fd = socket_network_client(__adb_server_name, __adb_server_port, SOCK_STREAM);
- else
+ } else {
fd = socket_loopback_client(__adb_server_port, SOCK_STREAM);
-
- if(fd < 0) {
+ }
+ if (fd < 0) {
*error = perror_str("cannot connect to daemon");
return -2;
}
- if (memcmp(service,"host",4) != 0 && switch_socket_transport(fd, error)) {
+ if (memcmp(&service[0],"host",4) != 0 && switch_socket_transport(fd, error)) {
return -1;
}
- if(!WriteFdExactly(fd, tmp, 4) || !WriteFdExactly(fd, service, len)) {
+ char tmp[5];
+ snprintf(tmp, sizeof(tmp), "%04zx", service.size());
+ if(!WriteFdExactly(fd, tmp, 4) || !WriteFdExactly(fd, &service[0], service.size())) {
*error = perror_str("write failure during connection");
adb_close(fd);
return -1;
@@ -225,11 +216,11 @@ int _adb_connect(const char *service, std::string* error) {
return fd;
}
-int adb_connect(const char* service, std::string* error) {
+int adb_connect(const std::string& service, std::string* error) {
// first query the adb server's version
int fd = _adb_connect("host:version", error);
- D("adb_connect: service %s\n", service);
+ D("adb_connect: service %s\n", service.c_str());
if (fd == -2 && __adb_server_name) {
fprintf(stderr,"** Cannot start server on remote host\n");
return fd;
@@ -248,21 +239,20 @@ int adb_connect(const char* service, std::string* error) {
// fall through to _adb_connect
} else {
// if server was running, check its version to make sure it is not out of date
- char buf[100];
- size_t n;
int version = ADB_SERVER_VERSION - 1;
// if we have a file descriptor, then parse version result
if (fd >= 0) {
- if(!ReadFdExactly(fd, buf, 4)) goto error;
+ std::string version_string;
+ if (!ReadProtocolString(fd, &version_string, error)) {
+ goto error;
+ }
- buf[4] = 0;
- n = strtoul(buf, 0, 16);
- if(n > sizeof(buf)) goto error;
- if(!ReadFdExactly(fd, buf, n)) goto error;
adb_close(fd);
- if (sscanf(buf, "%04x", &version) != 1) goto error;
+ if (sscanf(&version_string[0], "%04x", &version) != 1) {
+ goto error;
+ }
} else {
// if fd is -1, then check for "unknown host service",
// which would indicate a version of adb that does not support the version command
@@ -271,7 +261,7 @@ int adb_connect(const char* service, std::string* error) {
}
}
- if(version != ADB_SERVER_VERSION) {
+ if (version != ADB_SERVER_VERSION) {
printf("adb server is out of date. killing...\n");
fd = _adb_connect("host:kill", error);
adb_close(fd);
@@ -283,7 +273,7 @@ int adb_connect(const char* service, std::string* error) {
}
// if the command is start-server, we are done.
- if (!strcmp(service, "host:start-server")) {
+ if (service == "host:start-server") {
return 0;
}
@@ -302,7 +292,7 @@ error:
}
-int adb_command(const char* service, std::string* error) {
+int adb_command(const std::string& service, std::string* error) {
int fd = adb_connect(service, error);
if (fd < 0) {
fprintf(stderr, "error: %s\n", error->c_str());
@@ -317,39 +307,18 @@ int adb_command(const char* service, std::string* error) {
return 0;
}
-char* adb_query(const char* service, std::string* error) {
- char buf[5];
- unsigned long n;
- char* tmp;
-
- D("adb_query: %s\n", service);
+bool adb_query(const std::string& service, std::string* result, std::string* error) {
+ D("adb_query: %s\n", service.c_str());
int fd = adb_connect(service, error);
if (fd < 0) {
fprintf(stderr,"error: %s\n", error->c_str());
return 0;
}
- if (!ReadFdExactly(fd, buf, 4)) goto oops;
-
- buf[4] = 0;
- n = strtoul(buf, 0, 16);
- // TODO: given that we just read a 4-byte hex length 0x????, why the test?
- if (n >= 0xffff) {
- *error = "reply is too long (>= 64KiB)";
- goto oops;
- }
-
- tmp = reinterpret_cast<char*>(malloc(n + 1));
- if(tmp == 0) goto oops;
-
- if(!ReadFdExactly(fd, tmp, n) == 0) {
- tmp[n] = 0;
+ result->clear();
+ if (!ReadProtocolString(fd, result, error)) {
adb_close(fd);
- return tmp;
+ return false;
}
- free(tmp);
-
-oops:
- adb_close(fd);
- return 0;
+ return true;
}