adb: allow use of arbitrary socket specs for command socket. am: 9c869b58a8
am: 15f75ef520
Change-Id: Iab390aeb784541535da85cc8d6f734339f0c1ed7
This commit is contained in:
commit
df3b28c002
8 changed files with 92 additions and 82 deletions
13
adb/adb.cpp
13
adb/adb.cpp
|
|
@ -611,8 +611,7 @@ static unsigned __stdcall _redirect_stderr_thread(HANDLE h) {
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int launch_server(int server_port)
|
int launch_server(const std::string& socket_spec) {
|
||||||
{
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
/* we need to start the server in the background */
|
/* we need to start the server in the background */
|
||||||
/* we create a PIPE that will be used to wait for the server's "OK" */
|
/* we create a PIPE that will be used to wait for the server's "OK" */
|
||||||
|
|
@ -715,9 +714,8 @@ int launch_server(int server_port)
|
||||||
}
|
}
|
||||||
|
|
||||||
WCHAR args[64];
|
WCHAR args[64];
|
||||||
snwprintf(args, arraysize(args),
|
snwprintf(args, arraysize(args), L"adb -L %s fork-server server --reply-fd %d",
|
||||||
L"adb -P %d fork-server server --reply-fd %d", server_port,
|
socket_spec.c_str(), ack_write_as_int);
|
||||||
ack_write_as_int);
|
|
||||||
|
|
||||||
PROCESS_INFORMATION pinfo;
|
PROCESS_INFORMATION pinfo;
|
||||||
ZeroMemory(&pinfo, sizeof(pinfo));
|
ZeroMemory(&pinfo, sizeof(pinfo));
|
||||||
|
|
@ -862,12 +860,11 @@ int launch_server(int server_port)
|
||||||
|
|
||||||
adb_close(fd[0]);
|
adb_close(fd[0]);
|
||||||
|
|
||||||
char str_port[30];
|
|
||||||
snprintf(str_port, sizeof(str_port), "%d", server_port);
|
|
||||||
char reply_fd[30];
|
char reply_fd[30];
|
||||||
snprintf(reply_fd, sizeof(reply_fd), "%d", fd[1]);
|
snprintf(reply_fd, sizeof(reply_fd), "%d", fd[1]);
|
||||||
// child process
|
// child process
|
||||||
int result = execl(path.c_str(), "adb", "-P", str_port, "fork-server", "server", "--reply-fd", reply_fd, NULL);
|
int result = execl(path.c_str(), "adb", "-L", socket_spec.c_str(), "fork-server", "server",
|
||||||
|
"--reply-fd", reply_fd, NULL);
|
||||||
// this should not return
|
// this should not return
|
||||||
fprintf(stderr, "OOPS! execl returned %d, errno: %d\n", result, errno);
|
fprintf(stderr, "OOPS! execl returned %d, errno: %d\n", result, errno);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -126,8 +126,8 @@ void fatal_errno(const char* fmt, ...) __attribute__((noreturn, format(__printf_
|
||||||
|
|
||||||
void handle_packet(apacket *p, atransport *t);
|
void handle_packet(apacket *p, atransport *t);
|
||||||
|
|
||||||
int launch_server(int server_port);
|
int launch_server(const std::string& socket_spec);
|
||||||
int adb_server_main(int is_daemon, int server_port, int ack_reply_fd);
|
int adb_server_main(int is_daemon, const std::string& socket_spec, int ack_reply_fd);
|
||||||
|
|
||||||
/* initialize a transport object's func pointers and state */
|
/* initialize a transport object's func pointers and state */
|
||||||
#if ADB_HOST
|
#if ADB_HOST
|
||||||
|
|
|
||||||
|
|
@ -37,12 +37,12 @@
|
||||||
|
|
||||||
#include "adb_io.h"
|
#include "adb_io.h"
|
||||||
#include "adb_utils.h"
|
#include "adb_utils.h"
|
||||||
|
#include "socket_spec.h"
|
||||||
|
|
||||||
static TransportType __adb_transport = kTransportAny;
|
static TransportType __adb_transport = kTransportAny;
|
||||||
static const char* __adb_serial = NULL;
|
static const char* __adb_serial = NULL;
|
||||||
|
|
||||||
static int __adb_server_port = DEFAULT_ADB_PORT;
|
static const char* __adb_server_socket_spec;
|
||||||
static const char* __adb_server_name = NULL;
|
|
||||||
|
|
||||||
void adb_set_transport(TransportType type, const char* serial)
|
void adb_set_transport(TransportType type, const char* serial)
|
||||||
{
|
{
|
||||||
|
|
@ -59,14 +59,11 @@ void adb_get_transport(TransportType* type, const char** serial) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void adb_set_tcp_specifics(int server_port)
|
void adb_set_socket_spec(const char* socket_spec) {
|
||||||
{
|
if (!__adb_server_socket_spec) {
|
||||||
__adb_server_port = server_port;
|
LOG(FATAL) << "attempted to reinitialize adb_server_socket_spec";
|
||||||
}
|
}
|
||||||
|
__adb_server_socket_spec = socket_spec;
|
||||||
void adb_set_tcp_name(const char* hostname)
|
|
||||||
{
|
|
||||||
__adb_server_name = hostname;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int switch_socket_transport(int fd, std::string* error) {
|
static int switch_socket_transport(int fd, std::string* error) {
|
||||||
|
|
@ -139,23 +136,12 @@ int _adb_connect(const std::string& service, std::string* error) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int fd;
|
|
||||||
std::string reason;
|
std::string reason;
|
||||||
if (__adb_server_name) {
|
int fd = socket_spec_connect(__adb_server_socket_spec, &reason);
|
||||||
fd = network_connect(__adb_server_name, __adb_server_port, SOCK_STREAM, 0, &reason);
|
if (fd < 0) {
|
||||||
if (fd == -1) {
|
*error = android::base::StringPrintf("cannot connect to daemon at %s: %s",
|
||||||
*error = android::base::StringPrintf("can't connect to %s:%d: %s",
|
__adb_server_socket_spec, reason.c_str());
|
||||||
__adb_server_name, __adb_server_port,
|
return -2;
|
||||||
reason.c_str());
|
|
||||||
return -2;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
fd = network_loopback_client(__adb_server_port, SOCK_STREAM, &reason);
|
|
||||||
if (fd == -1) {
|
|
||||||
*error = android::base::StringPrintf("cannot connect to daemon: %s",
|
|
||||||
reason.c_str());
|
|
||||||
return -2;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((memcmp(&service[0],"host",4) != 0 || service == "host:reconnect") &&
|
if ((memcmp(&service[0],"host",4) != 0 || service == "host:reconnect") &&
|
||||||
|
|
@ -185,15 +171,14 @@ int adb_connect(const std::string& service, std::string* error) {
|
||||||
int fd = _adb_connect("host:version", error);
|
int fd = _adb_connect("host:version", error);
|
||||||
|
|
||||||
D("adb_connect: service %s", service.c_str());
|
D("adb_connect: service %s", service.c_str());
|
||||||
if (fd == -2 && __adb_server_name) {
|
if (fd == -2 && !is_local_socket_spec(__adb_server_socket_spec)) {
|
||||||
fprintf(stderr,"** Cannot start server on remote host\n");
|
fprintf(stderr,"** Cannot start server on remote host\n");
|
||||||
// error is the original network connection error
|
// error is the original network connection error
|
||||||
return fd;
|
return fd;
|
||||||
} else if (fd == -2) {
|
} else if (fd == -2) {
|
||||||
fprintf(stdout,"* daemon not running. starting it now on port %d *\n",
|
fprintf(stdout, "* daemon not running. starting it now at %s *\n", __adb_server_socket_spec);
|
||||||
__adb_server_port);
|
|
||||||
start_server:
|
start_server:
|
||||||
if (launch_server(__adb_server_port)) {
|
if (launch_server(__adb_server_socket_spec)) {
|
||||||
fprintf(stderr,"* failed to start daemon *\n");
|
fprintf(stderr,"* failed to start daemon *\n");
|
||||||
// launch_server() has already printed detailed error info, so just
|
// launch_server() has already printed detailed error info, so just
|
||||||
// return a generic error string about the overall adb_connect()
|
// return a generic error string about the overall adb_connect()
|
||||||
|
|
|
||||||
|
|
@ -43,11 +43,9 @@ void adb_set_transport(TransportType type, const char* _Nullable serial);
|
||||||
// Get the preferred transport to connect to.
|
// Get the preferred transport to connect to.
|
||||||
void adb_get_transport(TransportType* _Nullable type, const char* _Nullable* _Nullable serial);
|
void adb_get_transport(TransportType* _Nullable type, const char* _Nullable* _Nullable serial);
|
||||||
|
|
||||||
// Set TCP specifics of the transport to use.
|
// Set the socket specification for the adb server.
|
||||||
void adb_set_tcp_specifics(int server_port);
|
// This function can only be called once, and the argument must live to the end of the process.
|
||||||
|
void adb_set_socket_spec(const char* _Nonnull socket_spec);
|
||||||
// Set TCP Hostname of the transport to use.
|
|
||||||
void adb_set_tcp_name(const char* _Nullable hostname);
|
|
||||||
|
|
||||||
// Send commands to the current emulator instance. Will fail if there is not
|
// Send commands to the current emulator instance. Will fail if there is not
|
||||||
// exactly one emulator connected (or if you use -s <serial> with a <serial>
|
// exactly one emulator connected (or if you use -s <serial> with a <serial>
|
||||||
|
|
|
||||||
|
|
@ -88,7 +88,7 @@ static BOOL WINAPI ctrlc_handler(DWORD type) {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int adb_server_main(int is_daemon, int server_port, int ack_reply_fd) {
|
int adb_server_main(int is_daemon, const std::string& socket_spec, int ack_reply_fd) {
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
// adb start-server starts us up with stdout and stderr hooked up to
|
// adb start-server starts us up with stdout and stderr hooked up to
|
||||||
// anonymous pipes. When the C Runtime sees this, it makes stderr and
|
// anonymous pipes. When the C Runtime sees this, it makes stderr and
|
||||||
|
|
@ -113,8 +113,7 @@ int adb_server_main(int is_daemon, int server_port, int ack_reply_fd) {
|
||||||
local_init(DEFAULT_ADB_LOCAL_TRANSPORT_PORT);
|
local_init(DEFAULT_ADB_LOCAL_TRANSPORT_PORT);
|
||||||
|
|
||||||
std::string error;
|
std::string error;
|
||||||
std::string local_name = android::base::StringPrintf("tcp:%d", server_port);
|
if (install_listener(socket_spec, "*smartsocket*", nullptr, 0, nullptr, &error)) {
|
||||||
if (install_listener(local_name, "*smartsocket*", nullptr, 0, nullptr, &error)) {
|
|
||||||
fatal("could not install *smartsocket* listener: %s", error.c_str());
|
fatal("could not install *smartsocket* listener: %s", error.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -101,6 +101,8 @@ static void help() {
|
||||||
" be an absolute path.\n"
|
" be an absolute path.\n"
|
||||||
" -H - Name of adb server host (default: localhost)\n"
|
" -H - Name of adb server host (default: localhost)\n"
|
||||||
" -P - Port of adb server (default: 5037)\n"
|
" -P - Port of adb server (default: 5037)\n"
|
||||||
|
" -L <socket> - listen on socket specifier for the adb server\n"
|
||||||
|
" (default: tcp:localhost:5037)\n"
|
||||||
" devices [-l] - list all connected devices\n"
|
" devices [-l] - list all connected devices\n"
|
||||||
" ('-l' will also list device qualifiers)\n"
|
" ('-l' will also list device qualifiers)\n"
|
||||||
" connect <host>[:<port>] - connect to a device via TCP/IP\n"
|
" connect <host>[:<port>] - connect to a device via TCP/IP\n"
|
||||||
|
|
@ -1422,18 +1424,9 @@ int adb_commandline(int argc, const char **argv) {
|
||||||
}
|
}
|
||||||
// TODO: also try TARGET_PRODUCT/TARGET_DEVICE as a hint
|
// TODO: also try TARGET_PRODUCT/TARGET_DEVICE as a hint
|
||||||
|
|
||||||
/* Validate and assign the server port */
|
const char* server_host_str = nullptr;
|
||||||
const char* server_port_str = getenv("ANDROID_ADB_SERVER_PORT");
|
const char* server_port_str = nullptr;
|
||||||
int server_port = DEFAULT_ADB_PORT;
|
const char* server_socket_str = nullptr;
|
||||||
if (server_port_str && strlen(server_port_str) > 0) {
|
|
||||||
server_port = strtol(server_port_str, nullptr, 0);
|
|
||||||
if (server_port <= 0 || server_port > 65535) {
|
|
||||||
fprintf(stderr,
|
|
||||||
"adb: Env var ANDROID_ADB_SERVER_PORT must be a positive number less than 65536. Got \"%s\"\n",
|
|
||||||
server_port_str);
|
|
||||||
return usage();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// We need to check for -d and -e before we look at $ANDROID_SERIAL.
|
// We need to check for -d and -e before we look at $ANDROID_SERIAL.
|
||||||
const char* serial = nullptr;
|
const char* serial = nullptr;
|
||||||
|
|
@ -1487,17 +1480,14 @@ int adb_commandline(int argc, const char **argv) {
|
||||||
} else if (!strcmp(argv[0],"-a")) {
|
} else if (!strcmp(argv[0],"-a")) {
|
||||||
gListenAll = 1;
|
gListenAll = 1;
|
||||||
} else if (!strncmp(argv[0], "-H", 2)) {
|
} else if (!strncmp(argv[0], "-H", 2)) {
|
||||||
const char *hostname = NULL;
|
|
||||||
if (argv[0][2] == '\0') {
|
if (argv[0][2] == '\0') {
|
||||||
if (argc < 2) return usage();
|
if (argc < 2) return usage();
|
||||||
hostname = argv[1];
|
server_host_str = argv[1];
|
||||||
argc--;
|
argc--;
|
||||||
argv++;
|
argv++;
|
||||||
} else {
|
} else {
|
||||||
hostname = argv[0] + 2;
|
server_host_str = argv[0] + 2;
|
||||||
}
|
}
|
||||||
adb_set_tcp_name(hostname);
|
|
||||||
|
|
||||||
} else if (!strncmp(argv[0], "-P", 2)) {
|
} else if (!strncmp(argv[0], "-P", 2)) {
|
||||||
if (argv[0][2] == '\0') {
|
if (argv[0][2] == '\0') {
|
||||||
if (argc < 2) return usage();
|
if (argc < 2) return usage();
|
||||||
|
|
@ -1507,34 +1497,58 @@ int adb_commandline(int argc, const char **argv) {
|
||||||
} else {
|
} else {
|
||||||
server_port_str = argv[0] + 2;
|
server_port_str = argv[0] + 2;
|
||||||
}
|
}
|
||||||
if (strlen(server_port_str) > 0) {
|
} else if (!strcmp(argv[0], "-L")) {
|
||||||
server_port = (int) strtol(server_port_str, NULL, 0);
|
if (argc < 2) return usage();
|
||||||
if (server_port <= 0 || server_port > 65535) {
|
server_socket_str = argv[1];
|
||||||
fprintf(stderr,
|
argc--;
|
||||||
"adb: port number must be a positive number less than 65536. Got \"%s\"\n",
|
argv++;
|
||||||
server_port_str);
|
|
||||||
return usage();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
fprintf(stderr,
|
|
||||||
"adb: port number must be a positive number less than 65536. Got empty string.\n");
|
|
||||||
return usage();
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
/* out of recognized modifiers and flags */
|
/* out of recognized modifiers and flags */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
argc--;
|
argc--;
|
||||||
argv++;
|
argv++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((server_host_str || server_port_str) && server_socket_str) {
|
||||||
|
fprintf(stderr, "adb: -L is incompatible with -H or -P\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If -L, -H, or -P are specified, ignore environment variables.
|
||||||
|
// Otherwise, prefer ADB_SERVER_SOCKET over ANDROID_ADB_SERVER_ADDRESS/PORT.
|
||||||
|
if (!(server_host_str || server_port_str || server_socket_str)) {
|
||||||
|
server_socket_str = server_socket_str ? server_socket_str : getenv("ADB_SERVER_SOCKET");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!server_socket_str) {
|
||||||
|
// tcp:1234 and tcp:localhost:1234 are different with -a, so don't default to localhost
|
||||||
|
server_host_str = server_host_str ? server_host_str : getenv("ANDROID_ADB_SERVER_ADDRESS");
|
||||||
|
|
||||||
|
long server_port = DEFAULT_ADB_PORT;
|
||||||
|
server_port_str = server_port_str ? server_port_str : getenv("ANDROID_ADB_SERVER_PORT");
|
||||||
|
|
||||||
|
int rc;
|
||||||
|
char* temp;
|
||||||
|
if (server_host_str) {
|
||||||
|
rc = asprintf(&temp, "tcp:%s:%ld", server_host_str, server_port);
|
||||||
|
} else {
|
||||||
|
rc = asprintf(&temp, "tcp:%ld", server_port);
|
||||||
|
}
|
||||||
|
if (rc < 0) {
|
||||||
|
fatal("failed to allocate server socket specification");
|
||||||
|
}
|
||||||
|
server_socket_str = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
adb_set_socket_spec(server_socket_str);
|
||||||
|
|
||||||
// If none of -d, -e, or -s were specified, try $ANDROID_SERIAL.
|
// If none of -d, -e, or -s were specified, try $ANDROID_SERIAL.
|
||||||
if (transport_type == kTransportAny && serial == nullptr) {
|
if (transport_type == kTransportAny && serial == nullptr) {
|
||||||
serial = getenv("ANDROID_SERIAL");
|
serial = getenv("ANDROID_SERIAL");
|
||||||
}
|
}
|
||||||
|
|
||||||
adb_set_transport(transport_type, serial);
|
adb_set_transport(transport_type, serial);
|
||||||
adb_set_tcp_specifics(server_port);
|
|
||||||
|
|
||||||
if (is_server) {
|
if (is_server) {
|
||||||
if (no_daemon || is_daemon) {
|
if (no_daemon || is_daemon) {
|
||||||
|
|
@ -1542,9 +1556,9 @@ int adb_commandline(int argc, const char **argv) {
|
||||||
fprintf(stderr, "reply fd for adb server to client communication not specified.\n");
|
fprintf(stderr, "reply fd for adb server to client communication not specified.\n");
|
||||||
return usage();
|
return usage();
|
||||||
}
|
}
|
||||||
r = adb_server_main(is_daemon, server_port, ack_reply_fd);
|
r = adb_server_main(is_daemon, server_socket_str, ack_reply_fd);
|
||||||
} else {
|
} else {
|
||||||
r = launch_server(server_port);
|
r = launch_server(server_socket_str);
|
||||||
}
|
}
|
||||||
if (r) {
|
if (r) {
|
||||||
fprintf(stderr,"* could not start server *\n");
|
fprintf(stderr,"* could not start server *\n");
|
||||||
|
|
|
||||||
|
|
@ -131,6 +131,22 @@ bool is_socket_spec(const std::string& spec) {
|
||||||
return StartsWith(spec, "tcp:");
|
return StartsWith(spec, "tcp:");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool is_local_socket_spec(const std::string& spec) {
|
||||||
|
for (const auto& it : kLocalSocketTypes) {
|
||||||
|
std::string prefix = it.first + ":";
|
||||||
|
if (StartsWith(spec, prefix.c_str())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string error;
|
||||||
|
std::string hostname;
|
||||||
|
if (!parse_tcp_spec(spec, &hostname, nullptr, &error)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return tcp_host_is_local(hostname);
|
||||||
|
}
|
||||||
|
|
||||||
int socket_spec_connect(const std::string& spec, std::string* error) {
|
int socket_spec_connect(const std::string& spec, std::string* error) {
|
||||||
if (StartsWith(spec, "tcp:")) {
|
if (StartsWith(spec, "tcp:")) {
|
||||||
std::string hostname;
|
std::string hostname;
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@
|
||||||
|
|
||||||
// Returns true if the argument starts with a plausible socket prefix.
|
// Returns true if the argument starts with a plausible socket prefix.
|
||||||
bool is_socket_spec(const std::string& spec);
|
bool is_socket_spec(const std::string& spec);
|
||||||
|
bool is_local_socket_spec(const std::string& spec);
|
||||||
|
|
||||||
int socket_spec_connect(const std::string& spec, std::string* error);
|
int socket_spec_connect(const std::string& spec, std::string* error);
|
||||||
int socket_spec_listen(const std::string& spec, std::string* error,
|
int socket_spec_listen(const std::string& spec, std::string* error,
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue