Merge "Fix error handling/reporting for "adb forward" and "adb reverse"."

This commit is contained in:
Elliott Hughes 2015-05-30 01:29:19 +00:00 committed by Gerrit Code Review
commit ce817c38d2
6 changed files with 86 additions and 153 deletions

View file

@ -721,56 +721,50 @@ int handle_forward_request(const char* service, TransportType type, const char*
return 1; return 1;
} }
if (!strncmp(service, "forward:",8) || if (!strncmp(service, "forward:", 8) || !strncmp(service, "killforward:", 12)) {
!strncmp(service, "killforward:",12)) { // killforward:local
char *local, *remote; // forward:(norebind:)?local;remote
atransport *transport; bool kill_forward = false;
bool no_rebind = false;
int createForward = strncmp(service, "kill", 4); if (android::base::StartsWith(service, "killforward:")) {
int no_rebind = 0; kill_forward = true;
service += 12;
local = strchr(service, ':') + 1; if (android::base::StartsWith(service, "norebind:")) {
no_rebind = true;
// Handle forward:norebind:<local>... here service += 9;
if (createForward && !strncmp(local, "norebind:", 9)) { }
no_rebind = 1; } else {
local = strchr(local, ':') + 1; service += 8;
} }
remote = strchr(local,';'); std::vector<std::string> pieces = android::base::Split(service, ";");
if (createForward) { if (kill_forward) {
// Check forward: parameter format: '<local>;<remote>' // Check killforward: parameter format: '<local>'
if(remote == 0) { if (pieces.size() != 1 || pieces[0].empty()) {
SendFail(reply_fd, "malformed forward spec"); SendFail(reply_fd, android::base::StringPrintf("bad killforward: %s", service));
return 1;
}
*remote++ = 0;
if((local[0] == 0) || (remote[0] == 0) || (remote[0] == '*')) {
SendFail(reply_fd, "malformed forward spec");
return 1; return 1;
} }
} else { } else {
// Check killforward: parameter format: '<local>' // Check forward: parameter format: '<local>;<remote>'
if (local[0] == 0) { if (pieces.size() != 2 || pieces[0].empty() || pieces[1].empty() || pieces[1][0] == '*') {
SendFail(reply_fd, "malformed forward spec"); SendFail(reply_fd, android::base::StringPrintf("bad forward: %s", service));
return 1; return 1;
} }
} }
std::string error_msg; std::string error_msg;
transport = acquire_one_transport(kCsAny, type, serial, &error_msg); atransport* transport = acquire_one_transport(kCsAny, type, serial, &error_msg);
if (!transport) { if (!transport) {
SendFail(reply_fd, error_msg); SendFail(reply_fd, error_msg);
return 1; return 1;
} }
InstallStatus r; InstallStatus r;
if (createForward) { if (kill_forward) {
r = install_listener(local, remote, transport, no_rebind); r = remove_listener(pieces[0].c_str(), transport);
} else { } else {
r = remove_listener(local, transport); r = install_listener(pieces[0], pieces[1].c_str(), transport, no_rebind);
} }
if (r == INSTALL_STATUS_OK) { if (r == INSTALL_STATUS_OK) {
#if ADB_HOST #if ADB_HOST
@ -783,7 +777,7 @@ int handle_forward_request(const char* service, TransportType type, const char*
std::string message; std::string message;
switch (r) { switch (r) {
case INSTALL_STATUS_OK: message = " "; break; case INSTALL_STATUS_OK: message = "success (!)"; break;
case INSTALL_STATUS_INTERNAL_ERROR: message = "internal error"; break; case INSTALL_STATUS_INTERNAL_ERROR: message = "internal error"; break;
case INSTALL_STATUS_CANNOT_BIND: case INSTALL_STATUS_CANNOT_BIND:
message = android::base::StringPrintf("cannot bind to socket: %s", strerror(errno)); message = android::base::StringPrintf("cannot bind to socket: %s", strerror(errno));
@ -791,7 +785,9 @@ int handle_forward_request(const char* service, TransportType type, const char*
case INSTALL_STATUS_CANNOT_REBIND: case INSTALL_STATUS_CANNOT_REBIND:
message = android::base::StringPrintf("cannot rebind existing socket: %s", strerror(errno)); message = android::base::StringPrintf("cannot rebind existing socket: %s", strerror(errno));
break; break;
case INSTALL_STATUS_LISTENER_NOT_FOUND: message = "listener not found"; break; case INSTALL_STATUS_LISTENER_NOT_FOUND:
message = android::base::StringPrintf("listener '%s' not found", service);
break;
} }
SendFail(reply_fd, message); SendFail(reply_fd, message);
return 1; return 1;

View file

@ -256,19 +256,21 @@ error:
} }
int adb_command(const std::string& service, std::string* error) { bool adb_command(const std::string& service) {
int fd = adb_connect(service, error); std::string error;
int fd = adb_connect(service, &error);
if (fd < 0) { if (fd < 0) {
fprintf(stderr, "error: %s\n", error->c_str()); fprintf(stderr, "error: %s\n", error.c_str());
return -1; return false;
} }
if (!adb_status(fd, error)) { if (!adb_status(fd, &error)) {
fprintf(stderr, "error: %s\n", error.c_str());
adb_close(fd); adb_close(fd);
return -1; return false;
} }
return 0; return true;
} }
bool adb_query(const std::string& service, std::string* result, std::string* error) { bool adb_query(const std::string& service, std::string* result, std::string* error) {

View file

@ -26,9 +26,9 @@
int adb_connect(const std::string& service, std::string* error); int adb_connect(const std::string& service, std::string* error);
int _adb_connect(const std::string& service, std::string* error); int _adb_connect(const std::string& service, std::string* error);
// Connect to adb, connect to the named service, return 0 if the connection // Connect to adb, connect to the named service, returns true if the connection
// succeeded AND the service returned OKAY. // succeeded AND the service returned OKAY. Outputs any returned error otherwise.
int adb_command(const std::string& service, std::string* error); bool adb_command(const std::string& service);
// Connects to the named adb service and fills 'result' with the response. // Connects to the named adb service and fills 'result' with the response.
// Returns true on success; returns false and fills 'error' on failure. // Returns true on success; returns false and fills 'error' on failure.

View file

@ -26,13 +26,12 @@
int gListenAll = 0; /* Not static because it is used in commandline.c. */ int gListenAll = 0; /* Not static because it is used in commandline.c. */
alistener listener_list = { static alistener listener_list = {
.next = &listener_list, .next = &listener_list,
.prev = &listener_list, .prev = &listener_list,
}; };
void ss_listener_event_func(int _fd, unsigned ev, void *_l) static void ss_listener_event_func(int _fd, unsigned ev, void *_l) {
{
asocket *s; asocket *s;
if(ev & FDE_READ) { if(ev & FDE_READ) {
@ -56,7 +55,7 @@ void ss_listener_event_func(int _fd, unsigned ev, void *_l)
} }
} }
void listener_event_func(int _fd, unsigned ev, void* _l) static void listener_event_func(int _fd, unsigned ev, void* _l)
{ {
alistener* listener = reinterpret_cast<alistener*>(_l); alistener* listener = reinterpret_cast<alistener*>(_l);
asocket *s; asocket *s;
@ -106,38 +105,27 @@ static void free_listener(alistener* l)
free(l); free(l);
} }
void listener_disconnect(void* listener, atransport* t) static void listener_disconnect(void* listener, atransport* t) {
{
free_listener(reinterpret_cast<alistener*>(listener)); free_listener(reinterpret_cast<alistener*>(listener));
} }
int local_name_to_fd(const char *name) static int local_name_to_fd(const char* name) {
{ if (!strncmp("tcp:", name, 4)) {
int port; int port = atoi(name + 4);
if(!strncmp("tcp:", name, 4)){
int ret;
port = atoi(name + 4);
if (gListenAll > 0) { if (gListenAll > 0) {
ret = socket_inaddr_any_server(port, SOCK_STREAM); return socket_inaddr_any_server(port, SOCK_STREAM);
} else { } else {
ret = socket_loopback_server(port, SOCK_STREAM); return socket_loopback_server(port, SOCK_STREAM);
} }
return ret;
} }
#ifndef HAVE_WIN32_IPC /* no Unix-domain sockets on Win32 */ #ifndef HAVE_WIN32_IPC /* no Unix-domain sockets on Win32 */
// It's non-sensical to support the "reserved" space on the adb host side // It's nonsensical to support the "reserved" space on the adb host side
if(!strncmp(name, "local:", 6)) { if (!strncmp(name, "local:", 6)) {
return socket_local_server(name + 6, return socket_local_server(name + 6, ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM);
ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM); } else if (!strncmp(name, "localabstract:", 14)) {
} else if(!strncmp(name, "localabstract:", 14)) { return socket_local_server(name + 14, ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM);
return socket_local_server(name + 14, } else if (!strncmp(name, "localfilesystem:", 16)) {
ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM); return socket_local_server(name + 16, ANDROID_SOCKET_NAMESPACE_FILESYSTEM, SOCK_STREAM);
} else if(!strncmp(name, "localfilesystem:", 16)) {
return socket_local_server(name + 16,
ANDROID_SOCKET_NAMESPACE_FILESYSTEM, SOCK_STREAM);
} }
#endif #endif

View file

@ -30,12 +30,6 @@ enum InstallStatus {
INSTALL_STATUS_LISTENER_NOT_FOUND = -4, INSTALL_STATUS_LISTENER_NOT_FOUND = -4,
}; };
extern alistener listener_list;
void listener_disconnect(void* _l, atransport* t);
void listener_event_func(int _fd, unsigned ev, void *_l);
void ss_listener_event_func(int _fd, unsigned ev, void *_l);
InstallStatus install_listener(const std::string& local_name, InstallStatus install_listener(const std::string& local_name,
const char* connect_to, const char* connect_to,
atransport* transport, atransport* transport,

View file

@ -680,14 +680,7 @@ static bool wait_for_device(const char* service, TransportType t, const char* se
} }
std::string cmd = format_host_command(service, t, serial); std::string cmd = format_host_command(service, t, serial);
std::string error; return adb_command(cmd);
if (adb_command(cmd, &error)) {
D("failure: %s *\n", error.c_str());
fprintf(stderr,"error: %s\n", error.c_str());
return false;
}
return true;
} }
static int send_shell_command(TransportType transport_type, const char* serial, static int send_shell_command(TransportType transport_type, const char* serial,
@ -1249,90 +1242,50 @@ int adb_commandline(int argc, const char **argv) {
if (argc != 1) return usage(); if (argc != 1) return usage();
return send_shell_command(transport_type, serial, "shell:bugreport"); return send_shell_command(transport_type, serial, "shell:bugreport");
} }
/* adb_command() wrapper commands */
else if (!strcmp(argv[0], "forward") || !strcmp(argv[0], "reverse")) { else if (!strcmp(argv[0], "forward") || !strcmp(argv[0], "reverse")) {
std::string cmd; bool reverse = !strcmp(argv[0], "reverse");
char host_prefix[64]; ++argv;
char reverse = (char) !strcmp(argv[0], "reverse"); --argc;
char remove = 0; if (argc < 1) return usage();
char remove_all = 0;
char list = 0;
char no_rebind = 0;
// Parse options here.
while (argc > 1 && argv[1][0] == '-') {
if (!strcmp(argv[1], "--list"))
list = 1;
else if (!strcmp(argv[1], "--remove"))
remove = 1;
else if (!strcmp(argv[1], "--remove-all"))
remove_all = 1;
else if (!strcmp(argv[1], "--no-rebind"))
no_rebind = 1;
else {
return usage();
}
argc--;
argv++;
}
// Ensure we can only use one option at a time.
if (list + remove + remove_all + no_rebind > 1) {
return usage();
}
// Determine the <host-prefix> for this command. // Determine the <host-prefix> for this command.
std::string host_prefix;
if (reverse) { if (reverse) {
snprintf(host_prefix, sizeof host_prefix, "reverse"); host_prefix = "reverse";
} else { } else {
if (serial) { if (serial) {
snprintf(host_prefix, sizeof host_prefix, "host-serial:%s", host_prefix = android::base::StringPrintf("host-serial:%s", serial);
serial);
} else if (transport_type == kTransportUsb) { } else if (transport_type == kTransportUsb) {
snprintf(host_prefix, sizeof host_prefix, "host-usb"); host_prefix = "host-usb";
} else if (transport_type == kTransportLocal) { } else if (transport_type == kTransportLocal) {
snprintf(host_prefix, sizeof host_prefix, "host-local"); host_prefix = "host-local";
} else { } else {
snprintf(host_prefix, sizeof host_prefix, "host"); host_prefix = "host";
} }
} }
// Implement forward --list std::string cmd;
if (list) { if (strcmp(argv[0], "--list") == 0) {
if (argc != 1) {
return usage();
}
std::string query = android::base::StringPrintf("%s:list-forward", host_prefix);
return adb_query_command(query);
}
// Implement forward --remove-all
else if (remove_all) {
if (argc != 1) return usage(); if (argc != 1) return usage();
cmd = android::base::StringPrintf("%s:killforward-all", host_prefix); return adb_query_command(host_prefix + ":list-forward");
} } else if (strcmp(argv[0], "--remove-all") == 0) {
if (argc != 1) return usage();
// Implement forward --remove <local> cmd = host_prefix + ":killforward-all";
else if (remove) { } else if (strcmp(argv[0], "--remove") == 0) {
// forward --remove <local>
if (argc != 2) return usage(); if (argc != 2) return usage();
cmd = android::base::StringPrintf("%s:killforward:%s", host_prefix, argv[1]); cmd = host_prefix + ":killforward:" + argv[1];
} } else if (strcmp(argv[0], "--no-rebind") == 0) {
// Or implement one of: // forward --no-rebind <local> <remote>
// forward <local> <remote>
// forward --no-rebind <local> <remote>
else {
if (argc != 3) return usage(); if (argc != 3) return usage();
const char* command = no_rebind ? "forward:norebind" : "forward"; cmd = host_prefix + ":forward:norebind:" + argv[1] + ";" + argv[2];
cmd = android::base::StringPrintf("%s:%s:%s;%s", host_prefix, command, argv[1], argv[2]); } else {
// forward <local> <remote>
if (argc != 2) return usage();
cmd = host_prefix + ":forward:" + argv[0] + ";" + argv[1];
} }
std::string error; return adb_command(cmd) ? 0 : 1;
if (adb_command(cmd, &error)) {
fprintf(stderr, "error: %s\n", error.c_str());
return 1;
}
return 0;
} }
/* do_sync_*() commands */ /* do_sync_*() commands */
else if (!strcmp(argv[0], "ls")) { else if (!strcmp(argv[0], "ls")) {