Loading adb/client/adb_client.cpp +67 −9 Original line number Diff line number Diff line Loading @@ -31,10 +31,12 @@ #include <condition_variable> #include <mutex> #include <optional> #include <string> #include <thread> #include <vector> #include <android-base/file.h> #include <android-base/stringprintf.h> #include <android-base/strings.h> #include <android-base/thread_annotations.h> Loading Loading @@ -214,15 +216,26 @@ int adb_connect(std::string_view service, std::string* error) { return adb_connect(nullptr, service, error); } int adb_connect(TransportId* transport, std::string_view service, std::string* error) { // first query the adb server's version #if defined(__linux__) std::optional<std::string> adb_get_server_executable_path() { int port; std::string error; if (!parse_tcp_socket_spec(__adb_server_socket_spec, nullptr, &port, nullptr, &error)) { LOG(FATAL) << "failed to parse server socket spec: " << error; } return adb_get_android_dir_path() + OS_PATH_SEPARATOR + "adb." + std::to_string(port); } #endif static bool __adb_check_server_version(std::string* error) { unique_fd fd(_adb_connect("host:version", nullptr, error)); LOG(DEBUG) << "adb_connect: service: " << service; if (fd == -2 && !is_local_socket_spec(__adb_server_socket_spec)) { bool local = is_local_socket_spec(__adb_server_socket_spec); if (fd == -2 && !local) { fprintf(stderr, "* cannot start server on remote host\n"); // error is the original network connection error return fd; return false; } else if (fd == -2) { fprintf(stderr, "* daemon not running; starting now at %s\n", __adb_server_socket_spec); start_server: Loading @@ -232,7 +245,7 @@ int adb_connect(TransportId* transport, std::string_view service, std::string* e // return a generic error string about the overall adb_connect() // that the caller requested. *error = "cannot connect to daemon"; return -1; return false; } else { fprintf(stderr, "* daemon started successfully\n"); } Loading @@ -254,18 +267,39 @@ int adb_connect(TransportId* transport, std::string_view service, std::string* e if (sscanf(&version_string[0], "%04x", &version) != 1) { *error = android::base::StringPrintf("cannot parse version string: %s", version_string.c_str()); return -1; return false; } } else { // If fd is -1 check for "unknown host service" which would // indicate a version of adb that does not support the // version command, in which case we should fall-through to kill it. if (*error != "unknown host service") { return fd; return false; } } if (version != ADB_SERVER_VERSION) { #if defined(__linux__) if (version > ADB_SERVER_VERSION && local) { // Try to re-exec the existing adb server's binary. constexpr const char* adb_reexeced = "adb (re-execed)"; if (strcmp(adb_reexeced, *__adb_argv) != 0) { __adb_argv[0] = adb_reexeced; std::optional<std::string> server_path_path = adb_get_server_executable_path(); std::string server_path; if (server_path_path && android::base::ReadFileToString(*server_path_path, &server_path)) { if (execve(server_path.c_str(), const_cast<char**>(__adb_argv), const_cast<char**>(__adb_envp)) == -1) { LOG(ERROR) << "failed to exec newer version at " << server_path; } // Fall-through to restarting the server. } } } #endif fprintf(stderr, "adb server version (%d) doesn't match this client (%d); killing...\n", version, ADB_SERVER_VERSION); adb_kill_server(); Loading @@ -273,12 +307,36 @@ int adb_connect(TransportId* transport, std::string_view service, std::string* e } } return true; } bool adb_check_server_version(std::string* error) { // Only check the version once per process, since this isn't atomic anyway. static std::once_flag once; static bool result; static std::string* err; std::call_once(once, []() { err = new std::string(); result = __adb_check_server_version(err); }); *error = *err; return result; } int adb_connect(TransportId* transport, std::string_view service, std::string* error) { LOG(DEBUG) << "adb_connect: service: " << service; // Query the adb server's version. if (!adb_check_server_version(error)) { return -1; } // if the command is start-server, we are done. if (service == "host:start-server") { return 0; } fd.reset(_adb_connect(service, transport, error)); unique_fd fd(_adb_connect(service, transport, error)); if (fd == -1) { D("_adb_connect error: %s", error->c_str()); } else if(fd == -2) { Loading adb/client/adb_client.h +16 −0 Original line number Diff line number Diff line Loading @@ -20,8 +20,14 @@ #include "sysdeps.h" #include "transport.h" #include <optional> #include <string> // Explicitly check the adb server version. // All of the commands below do this implicitly. // Only the first invocation of this function will check the server version. bool adb_check_server_version(std::string* _Nonnull error); // Connect to adb, connect to the named service, and return a valid fd for // interacting with that service upon success or a negative number on failure. int adb_connect(std::string_view service, std::string* _Nonnull error); Loading Loading @@ -65,3 +71,13 @@ std::string format_host_command(const char* _Nonnull command); // Get the feature set of the current preferred transport. bool adb_get_feature_set(FeatureSet* _Nonnull feature_set, std::string* _Nonnull error); #if defined(__linux__) // Get the path of a file containing the path to the server executable, if the socket spec set via // adb_set_socket_spec is a local one. std::optional<std::string> adb_get_server_executable_path(); #endif // Globally acccesible argv/envp, for the purpose of re-execing adb. extern const char* _Nullable * _Nullable __adb_argv; extern const char* _Nullable * _Nullable __adb_envp; adb/client/commandline.cpp +11 −7 Original line number Diff line number Diff line Loading @@ -1303,9 +1303,9 @@ static void parse_push_pull_args(const char** arg, int narg, std::vector<const c } } static int adb_connect_command(const std::string& command) { static int adb_connect_command(const std::string& command, TransportId* transport = nullptr) { std::string error; unique_fd fd(adb_connect(command, &error)); unique_fd fd(adb_connect(transport, command, &error)); if (fd < 0) { fprintf(stderr, "error: %s\n", error.c_str()); return 1; Loading Loading @@ -1569,6 +1569,10 @@ int adb_commandline(int argc, const char** argv) { } std::string query = android::base::StringPrintf("host:%s%s", argv[0], listopt); std::string error; if (!adb_check_server_version(&error)) { error_exit("failed to check server version: %s", error.c_str()); } printf("List of devices attached\n"); return adb_query_command(query); } Loading adb/client/main.cpp +22 −2 Original line number Diff line number Diff line Loading @@ -32,12 +32,16 @@ #include "adb.h" #include "adb_auth.h" #include "adb_client.h" #include "adb_listeners.h" #include "adb_utils.h" #include "commandline.h" #include "sysdeps/chrono.h" #include "transport.h" const char** __adb_argv; const char** __adb_envp; static void setup_daemon_logging() { const std::string log_file_path(GetLogFilePath()); int fd = unix_open(log_file_path, O_WRONLY | O_CREAT | O_APPEND, 0640); Loading Loading @@ -191,13 +195,29 @@ int adb_server_main(int is_daemon, const std::string& socket_spec, int ack_reply notify_thread.detach(); } #if defined(__linux__) // Write our location to .android/adb.$PORT, so that older clients can exec us. std::string path; if (!android::base::Readlink("/proc/self/exe", &path)) { PLOG(ERROR) << "failed to readlink /proc/self/exe"; } std::optional<std::string> server_executable_path = adb_get_server_executable_path(); if (server_executable_path) { if (!android::base::WriteStringToFile(path, *server_executable_path)) { PLOG(ERROR) << "failed to write server path to " << path; } } #endif D("Event loop starting"); fdevent_loop(); return 0; } int main(int argc, char** argv) { int main(int argc, char* argv[], char* envp[]) { __adb_argv = const_cast<const char**>(argv); __adb_envp = const_cast<const char**>(envp); adb_trace_init(argv); return adb_commandline(argc - 1, const_cast<const char**>(argv + 1)); } adb/socket_spec.h +0 −1 Original line number Diff line number Diff line Loading @@ -29,6 +29,5 @@ bool socket_spec_connect(unique_fd* fd, std::string_view address, int* port, std 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(std::string_view spec, std::string* hostname, int* port, std::string* serial, std::string* error); Loading
adb/client/adb_client.cpp +67 −9 Original line number Diff line number Diff line Loading @@ -31,10 +31,12 @@ #include <condition_variable> #include <mutex> #include <optional> #include <string> #include <thread> #include <vector> #include <android-base/file.h> #include <android-base/stringprintf.h> #include <android-base/strings.h> #include <android-base/thread_annotations.h> Loading Loading @@ -214,15 +216,26 @@ int adb_connect(std::string_view service, std::string* error) { return adb_connect(nullptr, service, error); } int adb_connect(TransportId* transport, std::string_view service, std::string* error) { // first query the adb server's version #if defined(__linux__) std::optional<std::string> adb_get_server_executable_path() { int port; std::string error; if (!parse_tcp_socket_spec(__adb_server_socket_spec, nullptr, &port, nullptr, &error)) { LOG(FATAL) << "failed to parse server socket spec: " << error; } return adb_get_android_dir_path() + OS_PATH_SEPARATOR + "adb." + std::to_string(port); } #endif static bool __adb_check_server_version(std::string* error) { unique_fd fd(_adb_connect("host:version", nullptr, error)); LOG(DEBUG) << "adb_connect: service: " << service; if (fd == -2 && !is_local_socket_spec(__adb_server_socket_spec)) { bool local = is_local_socket_spec(__adb_server_socket_spec); if (fd == -2 && !local) { fprintf(stderr, "* cannot start server on remote host\n"); // error is the original network connection error return fd; return false; } else if (fd == -2) { fprintf(stderr, "* daemon not running; starting now at %s\n", __adb_server_socket_spec); start_server: Loading @@ -232,7 +245,7 @@ int adb_connect(TransportId* transport, std::string_view service, std::string* e // return a generic error string about the overall adb_connect() // that the caller requested. *error = "cannot connect to daemon"; return -1; return false; } else { fprintf(stderr, "* daemon started successfully\n"); } Loading @@ -254,18 +267,39 @@ int adb_connect(TransportId* transport, std::string_view service, std::string* e if (sscanf(&version_string[0], "%04x", &version) != 1) { *error = android::base::StringPrintf("cannot parse version string: %s", version_string.c_str()); return -1; return false; } } else { // If fd is -1 check for "unknown host service" which would // indicate a version of adb that does not support the // version command, in which case we should fall-through to kill it. if (*error != "unknown host service") { return fd; return false; } } if (version != ADB_SERVER_VERSION) { #if defined(__linux__) if (version > ADB_SERVER_VERSION && local) { // Try to re-exec the existing adb server's binary. constexpr const char* adb_reexeced = "adb (re-execed)"; if (strcmp(adb_reexeced, *__adb_argv) != 0) { __adb_argv[0] = adb_reexeced; std::optional<std::string> server_path_path = adb_get_server_executable_path(); std::string server_path; if (server_path_path && android::base::ReadFileToString(*server_path_path, &server_path)) { if (execve(server_path.c_str(), const_cast<char**>(__adb_argv), const_cast<char**>(__adb_envp)) == -1) { LOG(ERROR) << "failed to exec newer version at " << server_path; } // Fall-through to restarting the server. } } } #endif fprintf(stderr, "adb server version (%d) doesn't match this client (%d); killing...\n", version, ADB_SERVER_VERSION); adb_kill_server(); Loading @@ -273,12 +307,36 @@ int adb_connect(TransportId* transport, std::string_view service, std::string* e } } return true; } bool adb_check_server_version(std::string* error) { // Only check the version once per process, since this isn't atomic anyway. static std::once_flag once; static bool result; static std::string* err; std::call_once(once, []() { err = new std::string(); result = __adb_check_server_version(err); }); *error = *err; return result; } int adb_connect(TransportId* transport, std::string_view service, std::string* error) { LOG(DEBUG) << "adb_connect: service: " << service; // Query the adb server's version. if (!adb_check_server_version(error)) { return -1; } // if the command is start-server, we are done. if (service == "host:start-server") { return 0; } fd.reset(_adb_connect(service, transport, error)); unique_fd fd(_adb_connect(service, transport, error)); if (fd == -1) { D("_adb_connect error: %s", error->c_str()); } else if(fd == -2) { Loading
adb/client/adb_client.h +16 −0 Original line number Diff line number Diff line Loading @@ -20,8 +20,14 @@ #include "sysdeps.h" #include "transport.h" #include <optional> #include <string> // Explicitly check the adb server version. // All of the commands below do this implicitly. // Only the first invocation of this function will check the server version. bool adb_check_server_version(std::string* _Nonnull error); // Connect to adb, connect to the named service, and return a valid fd for // interacting with that service upon success or a negative number on failure. int adb_connect(std::string_view service, std::string* _Nonnull error); Loading Loading @@ -65,3 +71,13 @@ std::string format_host_command(const char* _Nonnull command); // Get the feature set of the current preferred transport. bool adb_get_feature_set(FeatureSet* _Nonnull feature_set, std::string* _Nonnull error); #if defined(__linux__) // Get the path of a file containing the path to the server executable, if the socket spec set via // adb_set_socket_spec is a local one. std::optional<std::string> adb_get_server_executable_path(); #endif // Globally acccesible argv/envp, for the purpose of re-execing adb. extern const char* _Nullable * _Nullable __adb_argv; extern const char* _Nullable * _Nullable __adb_envp;
adb/client/commandline.cpp +11 −7 Original line number Diff line number Diff line Loading @@ -1303,9 +1303,9 @@ static void parse_push_pull_args(const char** arg, int narg, std::vector<const c } } static int adb_connect_command(const std::string& command) { static int adb_connect_command(const std::string& command, TransportId* transport = nullptr) { std::string error; unique_fd fd(adb_connect(command, &error)); unique_fd fd(adb_connect(transport, command, &error)); if (fd < 0) { fprintf(stderr, "error: %s\n", error.c_str()); return 1; Loading Loading @@ -1569,6 +1569,10 @@ int adb_commandline(int argc, const char** argv) { } std::string query = android::base::StringPrintf("host:%s%s", argv[0], listopt); std::string error; if (!adb_check_server_version(&error)) { error_exit("failed to check server version: %s", error.c_str()); } printf("List of devices attached\n"); return adb_query_command(query); } Loading
adb/client/main.cpp +22 −2 Original line number Diff line number Diff line Loading @@ -32,12 +32,16 @@ #include "adb.h" #include "adb_auth.h" #include "adb_client.h" #include "adb_listeners.h" #include "adb_utils.h" #include "commandline.h" #include "sysdeps/chrono.h" #include "transport.h" const char** __adb_argv; const char** __adb_envp; static void setup_daemon_logging() { const std::string log_file_path(GetLogFilePath()); int fd = unix_open(log_file_path, O_WRONLY | O_CREAT | O_APPEND, 0640); Loading Loading @@ -191,13 +195,29 @@ int adb_server_main(int is_daemon, const std::string& socket_spec, int ack_reply notify_thread.detach(); } #if defined(__linux__) // Write our location to .android/adb.$PORT, so that older clients can exec us. std::string path; if (!android::base::Readlink("/proc/self/exe", &path)) { PLOG(ERROR) << "failed to readlink /proc/self/exe"; } std::optional<std::string> server_executable_path = adb_get_server_executable_path(); if (server_executable_path) { if (!android::base::WriteStringToFile(path, *server_executable_path)) { PLOG(ERROR) << "failed to write server path to " << path; } } #endif D("Event loop starting"); fdevent_loop(); return 0; } int main(int argc, char** argv) { int main(int argc, char* argv[], char* envp[]) { __adb_argv = const_cast<const char**>(argv); __adb_envp = const_cast<const char**>(envp); adb_trace_init(argv); return adb_commandline(argc - 1, const_cast<const char**>(argv + 1)); }
adb/socket_spec.h +0 −1 Original line number Diff line number Diff line Loading @@ -29,6 +29,5 @@ bool socket_spec_connect(unique_fd* fd, std::string_view address, int* port, std 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(std::string_view spec, std::string* hostname, int* port, std::string* serial, std::string* error);