Loading adb/Android.mk +1 −0 Original line number Original line Diff line number Diff line Loading @@ -58,6 +58,7 @@ LIBADB_SRC_FILES := \ LIBADB_TEST_SRCS := \ LIBADB_TEST_SRCS := \ adb_io_test.cpp \ adb_io_test.cpp \ adb_listeners_test.cpp \ adb_utils_test.cpp \ adb_utils_test.cpp \ fdevent_test.cpp \ fdevent_test.cpp \ socket_test.cpp \ socket_test.cpp \ Loading adb/adb.cpp +10 −3 Original line number Original line Diff line number Diff line Loading @@ -955,18 +955,25 @@ int handle_forward_request(const char* service, TransportType type, const char* std::string error; std::string error; InstallStatus r; InstallStatus r; int resolved_tcp_port = 0; if (kill_forward) { if (kill_forward) { r = remove_listener(pieces[0].c_str(), transport); r = remove_listener(pieces[0].c_str(), transport); } else { } else { r = install_listener(pieces[0], pieces[1].c_str(), transport, r = install_listener(pieces[0], pieces[1].c_str(), transport, no_rebind, no_rebind, &error); &resolved_tcp_port, &error); } } if (r == INSTALL_STATUS_OK) { if (r == INSTALL_STATUS_OK) { #if ADB_HOST #if ADB_HOST /* On the host: 1st OKAY is connect, 2nd OKAY is status */ // On the host: 1st OKAY is connect, 2nd OKAY is status. SendOkay(reply_fd); SendOkay(reply_fd); #endif #endif SendOkay(reply_fd); SendOkay(reply_fd); // If a TCP port was resolved, send the actual port number back. if (resolved_tcp_port != 0) { SendProtocolString(reply_fd, android::base::StringPrintf("%d", resolved_tcp_port)); } return 1; return 1; } } Loading adb/adb.h +1 −24 Original line number Original line Diff line number Diff line Loading @@ -50,7 +50,7 @@ constexpr size_t MAX_PAYLOAD = MAX_PAYLOAD_V2; std::string adb_version(); std::string adb_version(); // Increment this when we want to force users to start a new adb server. // Increment this when we want to force users to start a new adb server. #define ADB_SERVER_VERSION 36 #define ADB_SERVER_VERSION 37 class atransport; class atransport; struct usb_handle; struct usb_handle; Loading Loading @@ -116,29 +116,6 @@ enum ConnectionState { kCsUnauthorized, kCsUnauthorized, }; }; /* A listener is an entity which binds to a local port ** and, upon receiving a connection on that port, creates ** an asocket to connect the new local connection to a ** specific remote service. ** ** TODO: some listeners read from the new connection to ** determine what exact service to connect to on the far ** side. */ struct alistener { alistener *next; alistener *prev; fdevent fde; int fd; char *local_name; char *connect_to; atransport *transport; adisconnect disconnect; }; void print_packet(const char *label, apacket *p); void print_packet(const char *label, apacket *p); Loading adb/adb_listeners.cpp +111 −116 Original line number Original line Diff line number Diff line Loading @@ -20,18 +20,55 @@ #include <stdlib.h> #include <stdlib.h> #include <android-base/stringprintf.h> #include <android-base/stringprintf.h> #include <android-base/strings.h> #include <cutils/sockets.h> #include <cutils/sockets.h> #include "sysdeps.h" #include "sysdeps.h" #include "transport.h" #include "transport.h" int gListenAll = 0; /* Not static because it is used in commandline.c. */ // Not static because it is used in commandline.c. int gListenAll = 0; static alistener listener_list = { .next = &listener_list, // A listener is an entity which binds to a local port and, upon receiving a connection on that .prev = &listener_list, // port, creates an asocket to connect the new local connection to a specific remote service. // // TODO: some listeners read from the new connection to determine what exact service to connect to // on the far side. class alistener { public: alistener(const std::string& _local_name, const std::string& _connect_to); ~alistener(); fdevent fde; int fd = -1; std::string local_name; std::string connect_to; atransport* transport = nullptr; adisconnect disconnect; private: DISALLOW_COPY_AND_ASSIGN(alistener); }; }; alistener::alistener(const std::string& _local_name, const std::string& _connect_to) : local_name(_local_name), connect_to(_connect_to) { } alistener::~alistener() { // Closes the corresponding fd. fdevent_remove(&fde); if (transport) { transport->RemoveDisconnect(&disconnect); } } // listener_list retains ownership of all created alistener objects. Removing an alistener from // this list will cause it to be deleted. typedef std::list<std::unique_ptr<alistener>> ListenerList; static ListenerList& listener_list = *new ListenerList(); static void ss_listener_event_func(int _fd, unsigned ev, void *_l) { static void ss_listener_event_func(int _fd, unsigned ev, void *_l) { if (ev & FDE_READ) { if (ev & FDE_READ) { sockaddr_storage ss; sockaddr_storage ss; Loading Loading @@ -73,7 +110,7 @@ static void listener_event_func(int _fd, unsigned ev, void* _l) s = create_local_socket(fd); s = create_local_socket(fd); if (s) { if (s) { s->transport = listener->transport; s->transport = listener->transport; connect_to_remote(s, listener->connect_to); connect_to_remote(s, listener->connect_to.c_str()); return; return; } } Loading @@ -81,66 +118,63 @@ static void listener_event_func(int _fd, unsigned ev, void* _l) } } } } static void free_listener(alistener* l) // Called as a transport disconnect function. |arg| is the raw alistener*. { static void listener_disconnect(void* arg, atransport*) { if (l->next) { for (auto iter = listener_list.begin(); iter != listener_list.end(); ++iter) { l->next->prev = l->prev; if (iter->get() == arg) { l->prev->next = l->next; (*iter)->transport = nullptr; l->next = l->prev = l; listener_list.erase(iter); } return; // closes the corresponding fd fdevent_remove(&l->fde); if (l->local_name) free((char*)l->local_name); if (l->connect_to) free((char*)l->connect_to); if (l->transport) { l->transport->RemoveDisconnect(&l->disconnect); } } free(l); } } static void listener_disconnect(void* arg, atransport*) { alistener* listener = reinterpret_cast<alistener*>(arg); listener->transport = nullptr; free_listener(listener); } } static int local_name_to_fd(const char* name, std::string* error) { int local_name_to_fd(alistener* listener, int* resolved_tcp_port, std::string* error) { if (!strncmp("tcp:", name, 4)) { if (android::base::StartsWith(listener->local_name, "tcp:")) { int port = atoi(name + 4); int requested_port = atoi(&listener->local_name[4]); int sock = -1; if (gListenAll > 0) { if (gListenAll > 0) { return network_inaddr_any_server(port, SOCK_STREAM, error); sock = network_inaddr_any_server(requested_port, SOCK_STREAM, error); } else { } else { return network_loopback_server(port, SOCK_STREAM, error); sock = network_loopback_server(requested_port, SOCK_STREAM, error); } // If the caller requested port 0, update the listener name with the resolved port. if (sock >= 0 && requested_port == 0) { int local_port = adb_socket_get_local_port(sock); if (local_port > 0) { listener->local_name = android::base::StringPrintf("tcp:%d", local_port); if (resolved_tcp_port != nullptr) { *resolved_tcp_port = local_port; } } } } } return sock; } #if !defined(_WIN32) // No Unix-domain sockets on Windows. #if !defined(_WIN32) // No Unix-domain sockets on Windows. // It's nonsensical 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 (android::base::StartsWith(listener->local_name, "local:")) { return network_local_server(name + 6, return network_local_server(&listener->local_name[6], ANDROID_SOCKET_NAMESPACE_ABSTRACT, ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM, error); SOCK_STREAM, error); } else if (!strncmp(name, "localabstract:", 14)) { } else if (android::base::StartsWith(listener->local_name, "localabstract:")) { return network_local_server(name + 14, return network_local_server(&listener->local_name[14], ANDROID_SOCKET_NAMESPACE_ABSTRACT, ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM, error); SOCK_STREAM, error); } else if (!strncmp(name, "localfilesystem:", 16)) { } else if (android::base::StartsWith(listener->local_name, "localfilesystem:")) { return network_local_server(name + 16, return network_local_server(&listener->local_name[16], ANDROID_SOCKET_NAMESPACE_FILESYSTEM, ANDROID_SOCKET_NAMESPACE_FILESYSTEM, SOCK_STREAM, error); SOCK_STREAM, error); } } #endif #endif *error = android::base::StringPrintf("unknown local portname '%s'", name); *error = android::base::StringPrintf("unknown local portname '%s'", listener->local_name.c_str()); return -1; return -1; } } // Write the list of current listeners (network redirections) into a string. // Write the list of current listeners (network redirections) into a string. std::string format_listeners() { std::string format_listeners() { std::string result; std::string result; for (alistener* l = listener_list.next; l != &listener_list; l = l->next) { for (auto& l : listener_list) { // Ignore special listeners like those for *smartsocket* // Ignore special listeners like those for *smartsocket* if (l->connect_to[0] == '*') { if (l->connect_to[0] == '*') { continue; continue; Loading @@ -149,65 +183,51 @@ std::string format_listeners() { // Entries from "adb reverse" have no serial. // Entries from "adb reverse" have no serial. android::base::StringAppendF(&result, "%s %s %s\n", android::base::StringAppendF(&result, "%s %s %s\n", l->transport->serial ? l->transport->serial : "(reverse)", l->transport->serial ? l->transport->serial : "(reverse)", l->local_name, l->connect_to); l->local_name.c_str(), l->connect_to.c_str()); } } return result; return result; } } InstallStatus remove_listener(const char* local_name, atransport* transport) { InstallStatus remove_listener(const char* local_name, atransport* transport) { alistener *l; for (auto iter = listener_list.begin(); iter != listener_list.end(); ++iter) { if (local_name == (*iter)->local_name) { for (l = listener_list.next; l != &listener_list; l = l->next) { listener_list.erase(iter); if (!strcmp(local_name, l->local_name)) { free_listener(l); return INSTALL_STATUS_OK; return INSTALL_STATUS_OK; } } } } return INSTALL_STATUS_LISTENER_NOT_FOUND; return INSTALL_STATUS_LISTENER_NOT_FOUND; } } void remove_all_listeners(void) void remove_all_listeners() { { auto iter = listener_list.begin(); alistener *l, *l_next; while (iter != listener_list.end()) { for (l = listener_list.next; l != &listener_list; l = l_next) { l_next = l->next; // Never remove smart sockets. // Never remove smart sockets. if (l->connect_to[0] == '*') if ((*iter)->connect_to[0] == '*') { continue; ++iter; free_listener(l); } else { iter = listener_list.erase(iter); } } } } } 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, int no_rebind, int* resolved_tcp_port, atransport* transport, std::string* error) { int no_rebind, for (auto& l : listener_list) { std::string* error) { for (alistener* l = listener_list.next; l != &listener_list; l = l->next) { if (local_name == l->local_name) { if (local_name == l->local_name) { char* cto; // Can't repurpose a smartsocket. /* can't repurpose a smartsocket */ if(l->connect_to[0] == '*') { if(l->connect_to[0] == '*') { *error = "cannot repurpose smartsocket"; *error = "cannot repurpose smartsocket"; return INSTALL_STATUS_INTERNAL_ERROR; return INSTALL_STATUS_INTERNAL_ERROR; } } /* can't repurpose a listener if 'no_rebind' is true */ // Can't repurpose a listener if 'no_rebind' is true. if (no_rebind) { if (no_rebind) { *error = "cannot rebind"; *error = "cannot rebind"; return INSTALL_STATUS_CANNOT_REBIND; return INSTALL_STATUS_CANNOT_REBIND; } } cto = strdup(connect_to); l->connect_to = connect_to; if(cto == 0) { *error = "cannot duplicate string"; return INSTALL_STATUS_INTERNAL_ERROR; } free((void*) l->connect_to); l->connect_to = cto; if (l->transport != transport) { if (l->transport != transport) { l->transport->RemoveDisconnect(&l->disconnect); l->transport->RemoveDisconnect(&l->disconnect); l->transport = transport; l->transport = transport; Loading @@ -217,54 +237,29 @@ InstallStatus install_listener(const std::string& local_name, } } } } alistener* listener = reinterpret_cast<alistener*>( std::unique_ptr<alistener> listener(new alistener(local_name, connect_to)); calloc(1, sizeof(alistener))); if (listener == nullptr) { goto nomem; } listener->local_name = strdup(local_name.c_str()); if (listener->local_name == nullptr) { goto nomem; } listener->connect_to = strdup(connect_to); if (listener->connect_to == nullptr) { goto nomem; } listener->fd = local_name_to_fd(listener->local_name, error); listener->fd = local_name_to_fd(listener.get(), resolved_tcp_port, error); if (listener->fd < 0) { if (listener->fd < 0) { free(listener->local_name); free(listener->connect_to); free(listener); return INSTALL_STATUS_CANNOT_BIND; return INSTALL_STATUS_CANNOT_BIND; } } close_on_exec(listener->fd); close_on_exec(listener->fd); if (!strcmp(listener->connect_to, "*smartsocket*")) { if (listener->connect_to == "*smartsocket*") { fdevent_install(&listener->fde, listener->fd, ss_listener_event_func, fdevent_install(&listener->fde, listener->fd, ss_listener_event_func, listener.get()); listener); } else { } else { fdevent_install(&listener->fde, listener->fd, listener_event_func, fdevent_install(&listener->fde, listener->fd, listener_event_func, listener.get()); listener); } } fdevent_set(&listener->fde, FDE_READ); fdevent_set(&listener->fde, FDE_READ); listener->next = &listener_list; listener->prev = listener_list.prev; listener->next->prev = listener; listener->prev->next = listener; listener->transport = transport; listener->transport = transport; if (transport) { if (transport) { listener->disconnect.opaque = listener; listener->disconnect.opaque = listener.get(); listener->disconnect.func = listener_disconnect; listener->disconnect.func = listener_disconnect; transport->AddDisconnect(&listener->disconnect); transport->AddDisconnect(&listener->disconnect); } } return INSTALL_STATUS_OK; nomem: listener_list.push_back(std::move(listener)); fatal("cannot allocate listener"); return INSTALL_STATUS_OK; return INSTALL_STATUS_INTERNAL_ERROR; } } adb/adb_listeners.h +4 −4 Original line number Original line Diff line number Diff line Loading @@ -21,6 +21,8 @@ #include <string> #include <string> #include <android-base/macros.h> // error/status codes for install_listener. // error/status codes for install_listener. enum InstallStatus { enum InstallStatus { INSTALL_STATUS_OK = 0, INSTALL_STATUS_OK = 0, Loading @@ -30,10 +32,8 @@ enum InstallStatus { INSTALL_STATUS_LISTENER_NOT_FOUND = -4, INSTALL_STATUS_LISTENER_NOT_FOUND = -4, }; }; 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, int no_rebind, int* resolved_tcp_port, atransport* transport, int no_rebind, std::string* error); std::string* error); std::string format_listeners(); std::string format_listeners(); Loading Loading
adb/Android.mk +1 −0 Original line number Original line Diff line number Diff line Loading @@ -58,6 +58,7 @@ LIBADB_SRC_FILES := \ LIBADB_TEST_SRCS := \ LIBADB_TEST_SRCS := \ adb_io_test.cpp \ adb_io_test.cpp \ adb_listeners_test.cpp \ adb_utils_test.cpp \ adb_utils_test.cpp \ fdevent_test.cpp \ fdevent_test.cpp \ socket_test.cpp \ socket_test.cpp \ Loading
adb/adb.cpp +10 −3 Original line number Original line Diff line number Diff line Loading @@ -955,18 +955,25 @@ int handle_forward_request(const char* service, TransportType type, const char* std::string error; std::string error; InstallStatus r; InstallStatus r; int resolved_tcp_port = 0; if (kill_forward) { if (kill_forward) { r = remove_listener(pieces[0].c_str(), transport); r = remove_listener(pieces[0].c_str(), transport); } else { } else { r = install_listener(pieces[0], pieces[1].c_str(), transport, r = install_listener(pieces[0], pieces[1].c_str(), transport, no_rebind, no_rebind, &error); &resolved_tcp_port, &error); } } if (r == INSTALL_STATUS_OK) { if (r == INSTALL_STATUS_OK) { #if ADB_HOST #if ADB_HOST /* On the host: 1st OKAY is connect, 2nd OKAY is status */ // On the host: 1st OKAY is connect, 2nd OKAY is status. SendOkay(reply_fd); SendOkay(reply_fd); #endif #endif SendOkay(reply_fd); SendOkay(reply_fd); // If a TCP port was resolved, send the actual port number back. if (resolved_tcp_port != 0) { SendProtocolString(reply_fd, android::base::StringPrintf("%d", resolved_tcp_port)); } return 1; return 1; } } Loading
adb/adb.h +1 −24 Original line number Original line Diff line number Diff line Loading @@ -50,7 +50,7 @@ constexpr size_t MAX_PAYLOAD = MAX_PAYLOAD_V2; std::string adb_version(); std::string adb_version(); // Increment this when we want to force users to start a new adb server. // Increment this when we want to force users to start a new adb server. #define ADB_SERVER_VERSION 36 #define ADB_SERVER_VERSION 37 class atransport; class atransport; struct usb_handle; struct usb_handle; Loading Loading @@ -116,29 +116,6 @@ enum ConnectionState { kCsUnauthorized, kCsUnauthorized, }; }; /* A listener is an entity which binds to a local port ** and, upon receiving a connection on that port, creates ** an asocket to connect the new local connection to a ** specific remote service. ** ** TODO: some listeners read from the new connection to ** determine what exact service to connect to on the far ** side. */ struct alistener { alistener *next; alistener *prev; fdevent fde; int fd; char *local_name; char *connect_to; atransport *transport; adisconnect disconnect; }; void print_packet(const char *label, apacket *p); void print_packet(const char *label, apacket *p); Loading
adb/adb_listeners.cpp +111 −116 Original line number Original line Diff line number Diff line Loading @@ -20,18 +20,55 @@ #include <stdlib.h> #include <stdlib.h> #include <android-base/stringprintf.h> #include <android-base/stringprintf.h> #include <android-base/strings.h> #include <cutils/sockets.h> #include <cutils/sockets.h> #include "sysdeps.h" #include "sysdeps.h" #include "transport.h" #include "transport.h" int gListenAll = 0; /* Not static because it is used in commandline.c. */ // Not static because it is used in commandline.c. int gListenAll = 0; static alistener listener_list = { .next = &listener_list, // A listener is an entity which binds to a local port and, upon receiving a connection on that .prev = &listener_list, // port, creates an asocket to connect the new local connection to a specific remote service. // // TODO: some listeners read from the new connection to determine what exact service to connect to // on the far side. class alistener { public: alistener(const std::string& _local_name, const std::string& _connect_to); ~alistener(); fdevent fde; int fd = -1; std::string local_name; std::string connect_to; atransport* transport = nullptr; adisconnect disconnect; private: DISALLOW_COPY_AND_ASSIGN(alistener); }; }; alistener::alistener(const std::string& _local_name, const std::string& _connect_to) : local_name(_local_name), connect_to(_connect_to) { } alistener::~alistener() { // Closes the corresponding fd. fdevent_remove(&fde); if (transport) { transport->RemoveDisconnect(&disconnect); } } // listener_list retains ownership of all created alistener objects. Removing an alistener from // this list will cause it to be deleted. typedef std::list<std::unique_ptr<alistener>> ListenerList; static ListenerList& listener_list = *new ListenerList(); static void ss_listener_event_func(int _fd, unsigned ev, void *_l) { static void ss_listener_event_func(int _fd, unsigned ev, void *_l) { if (ev & FDE_READ) { if (ev & FDE_READ) { sockaddr_storage ss; sockaddr_storage ss; Loading Loading @@ -73,7 +110,7 @@ static void listener_event_func(int _fd, unsigned ev, void* _l) s = create_local_socket(fd); s = create_local_socket(fd); if (s) { if (s) { s->transport = listener->transport; s->transport = listener->transport; connect_to_remote(s, listener->connect_to); connect_to_remote(s, listener->connect_to.c_str()); return; return; } } Loading @@ -81,66 +118,63 @@ static void listener_event_func(int _fd, unsigned ev, void* _l) } } } } static void free_listener(alistener* l) // Called as a transport disconnect function. |arg| is the raw alistener*. { static void listener_disconnect(void* arg, atransport*) { if (l->next) { for (auto iter = listener_list.begin(); iter != listener_list.end(); ++iter) { l->next->prev = l->prev; if (iter->get() == arg) { l->prev->next = l->next; (*iter)->transport = nullptr; l->next = l->prev = l; listener_list.erase(iter); } return; // closes the corresponding fd fdevent_remove(&l->fde); if (l->local_name) free((char*)l->local_name); if (l->connect_to) free((char*)l->connect_to); if (l->transport) { l->transport->RemoveDisconnect(&l->disconnect); } } free(l); } } static void listener_disconnect(void* arg, atransport*) { alistener* listener = reinterpret_cast<alistener*>(arg); listener->transport = nullptr; free_listener(listener); } } static int local_name_to_fd(const char* name, std::string* error) { int local_name_to_fd(alistener* listener, int* resolved_tcp_port, std::string* error) { if (!strncmp("tcp:", name, 4)) { if (android::base::StartsWith(listener->local_name, "tcp:")) { int port = atoi(name + 4); int requested_port = atoi(&listener->local_name[4]); int sock = -1; if (gListenAll > 0) { if (gListenAll > 0) { return network_inaddr_any_server(port, SOCK_STREAM, error); sock = network_inaddr_any_server(requested_port, SOCK_STREAM, error); } else { } else { return network_loopback_server(port, SOCK_STREAM, error); sock = network_loopback_server(requested_port, SOCK_STREAM, error); } // If the caller requested port 0, update the listener name with the resolved port. if (sock >= 0 && requested_port == 0) { int local_port = adb_socket_get_local_port(sock); if (local_port > 0) { listener->local_name = android::base::StringPrintf("tcp:%d", local_port); if (resolved_tcp_port != nullptr) { *resolved_tcp_port = local_port; } } } } } return sock; } #if !defined(_WIN32) // No Unix-domain sockets on Windows. #if !defined(_WIN32) // No Unix-domain sockets on Windows. // It's nonsensical 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 (android::base::StartsWith(listener->local_name, "local:")) { return network_local_server(name + 6, return network_local_server(&listener->local_name[6], ANDROID_SOCKET_NAMESPACE_ABSTRACT, ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM, error); SOCK_STREAM, error); } else if (!strncmp(name, "localabstract:", 14)) { } else if (android::base::StartsWith(listener->local_name, "localabstract:")) { return network_local_server(name + 14, return network_local_server(&listener->local_name[14], ANDROID_SOCKET_NAMESPACE_ABSTRACT, ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM, error); SOCK_STREAM, error); } else if (!strncmp(name, "localfilesystem:", 16)) { } else if (android::base::StartsWith(listener->local_name, "localfilesystem:")) { return network_local_server(name + 16, return network_local_server(&listener->local_name[16], ANDROID_SOCKET_NAMESPACE_FILESYSTEM, ANDROID_SOCKET_NAMESPACE_FILESYSTEM, SOCK_STREAM, error); SOCK_STREAM, error); } } #endif #endif *error = android::base::StringPrintf("unknown local portname '%s'", name); *error = android::base::StringPrintf("unknown local portname '%s'", listener->local_name.c_str()); return -1; return -1; } } // Write the list of current listeners (network redirections) into a string. // Write the list of current listeners (network redirections) into a string. std::string format_listeners() { std::string format_listeners() { std::string result; std::string result; for (alistener* l = listener_list.next; l != &listener_list; l = l->next) { for (auto& l : listener_list) { // Ignore special listeners like those for *smartsocket* // Ignore special listeners like those for *smartsocket* if (l->connect_to[0] == '*') { if (l->connect_to[0] == '*') { continue; continue; Loading @@ -149,65 +183,51 @@ std::string format_listeners() { // Entries from "adb reverse" have no serial. // Entries from "adb reverse" have no serial. android::base::StringAppendF(&result, "%s %s %s\n", android::base::StringAppendF(&result, "%s %s %s\n", l->transport->serial ? l->transport->serial : "(reverse)", l->transport->serial ? l->transport->serial : "(reverse)", l->local_name, l->connect_to); l->local_name.c_str(), l->connect_to.c_str()); } } return result; return result; } } InstallStatus remove_listener(const char* local_name, atransport* transport) { InstallStatus remove_listener(const char* local_name, atransport* transport) { alistener *l; for (auto iter = listener_list.begin(); iter != listener_list.end(); ++iter) { if (local_name == (*iter)->local_name) { for (l = listener_list.next; l != &listener_list; l = l->next) { listener_list.erase(iter); if (!strcmp(local_name, l->local_name)) { free_listener(l); return INSTALL_STATUS_OK; return INSTALL_STATUS_OK; } } } } return INSTALL_STATUS_LISTENER_NOT_FOUND; return INSTALL_STATUS_LISTENER_NOT_FOUND; } } void remove_all_listeners(void) void remove_all_listeners() { { auto iter = listener_list.begin(); alistener *l, *l_next; while (iter != listener_list.end()) { for (l = listener_list.next; l != &listener_list; l = l_next) { l_next = l->next; // Never remove smart sockets. // Never remove smart sockets. if (l->connect_to[0] == '*') if ((*iter)->connect_to[0] == '*') { continue; ++iter; free_listener(l); } else { iter = listener_list.erase(iter); } } } } } 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, int no_rebind, int* resolved_tcp_port, atransport* transport, std::string* error) { int no_rebind, for (auto& l : listener_list) { std::string* error) { for (alistener* l = listener_list.next; l != &listener_list; l = l->next) { if (local_name == l->local_name) { if (local_name == l->local_name) { char* cto; // Can't repurpose a smartsocket. /* can't repurpose a smartsocket */ if(l->connect_to[0] == '*') { if(l->connect_to[0] == '*') { *error = "cannot repurpose smartsocket"; *error = "cannot repurpose smartsocket"; return INSTALL_STATUS_INTERNAL_ERROR; return INSTALL_STATUS_INTERNAL_ERROR; } } /* can't repurpose a listener if 'no_rebind' is true */ // Can't repurpose a listener if 'no_rebind' is true. if (no_rebind) { if (no_rebind) { *error = "cannot rebind"; *error = "cannot rebind"; return INSTALL_STATUS_CANNOT_REBIND; return INSTALL_STATUS_CANNOT_REBIND; } } cto = strdup(connect_to); l->connect_to = connect_to; if(cto == 0) { *error = "cannot duplicate string"; return INSTALL_STATUS_INTERNAL_ERROR; } free((void*) l->connect_to); l->connect_to = cto; if (l->transport != transport) { if (l->transport != transport) { l->transport->RemoveDisconnect(&l->disconnect); l->transport->RemoveDisconnect(&l->disconnect); l->transport = transport; l->transport = transport; Loading @@ -217,54 +237,29 @@ InstallStatus install_listener(const std::string& local_name, } } } } alistener* listener = reinterpret_cast<alistener*>( std::unique_ptr<alistener> listener(new alistener(local_name, connect_to)); calloc(1, sizeof(alistener))); if (listener == nullptr) { goto nomem; } listener->local_name = strdup(local_name.c_str()); if (listener->local_name == nullptr) { goto nomem; } listener->connect_to = strdup(connect_to); if (listener->connect_to == nullptr) { goto nomem; } listener->fd = local_name_to_fd(listener->local_name, error); listener->fd = local_name_to_fd(listener.get(), resolved_tcp_port, error); if (listener->fd < 0) { if (listener->fd < 0) { free(listener->local_name); free(listener->connect_to); free(listener); return INSTALL_STATUS_CANNOT_BIND; return INSTALL_STATUS_CANNOT_BIND; } } close_on_exec(listener->fd); close_on_exec(listener->fd); if (!strcmp(listener->connect_to, "*smartsocket*")) { if (listener->connect_to == "*smartsocket*") { fdevent_install(&listener->fde, listener->fd, ss_listener_event_func, fdevent_install(&listener->fde, listener->fd, ss_listener_event_func, listener.get()); listener); } else { } else { fdevent_install(&listener->fde, listener->fd, listener_event_func, fdevent_install(&listener->fde, listener->fd, listener_event_func, listener.get()); listener); } } fdevent_set(&listener->fde, FDE_READ); fdevent_set(&listener->fde, FDE_READ); listener->next = &listener_list; listener->prev = listener_list.prev; listener->next->prev = listener; listener->prev->next = listener; listener->transport = transport; listener->transport = transport; if (transport) { if (transport) { listener->disconnect.opaque = listener; listener->disconnect.opaque = listener.get(); listener->disconnect.func = listener_disconnect; listener->disconnect.func = listener_disconnect; transport->AddDisconnect(&listener->disconnect); transport->AddDisconnect(&listener->disconnect); } } return INSTALL_STATUS_OK; nomem: listener_list.push_back(std::move(listener)); fatal("cannot allocate listener"); return INSTALL_STATUS_OK; return INSTALL_STATUS_INTERNAL_ERROR; } }
adb/adb_listeners.h +4 −4 Original line number Original line Diff line number Diff line Loading @@ -21,6 +21,8 @@ #include <string> #include <string> #include <android-base/macros.h> // error/status codes for install_listener. // error/status codes for install_listener. enum InstallStatus { enum InstallStatus { INSTALL_STATUS_OK = 0, INSTALL_STATUS_OK = 0, Loading @@ -30,10 +32,8 @@ enum InstallStatus { INSTALL_STATUS_LISTENER_NOT_FOUND = -4, INSTALL_STATUS_LISTENER_NOT_FOUND = -4, }; }; 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, int no_rebind, int* resolved_tcp_port, atransport* transport, int no_rebind, std::string* error); std::string* error); std::string format_listeners(); std::string format_listeners(); Loading