diff --git a/adb/adb.cpp b/adb/adb.cpp index 0181daa60a17592a69ba82c6771e8ea250872683..55c64ec4e883199f9fd319327991e0717b5b3f11 100644 --- a/adb/adb.cpp +++ b/adb/adb.cpp @@ -1054,15 +1054,12 @@ int handle_host_request(const char* service, TransportType type, if (strcmp(service, "kill") == 0) { fprintf(stderr, "adb server killed by remote request\n"); fflush(stdout); - SendOkay(reply_fd); - // On Windows, if the process exits with open sockets that - // shutdown(SD_SEND) has not been called on, TCP RST segments will be - // sent to the peers which will cause their next recv() to error-out - // with WSAECONNRESET. In the case of this code, that means the client - // may not read the OKAY sent above. - adb_shutdown(reply_fd); + // Send a reply even though we don't read it anymore, so that old versions + // of adb that do read it don't spew error messages. + SendOkay(reply_fd); + // Rely on process exit to close the socket for us. android::base::quick_exit(0); } diff --git a/adb/adb_client.cpp b/adb/adb_client.cpp index 4f3ff25dfcacde58abcc1cbf55e1ef519ab35c08..f5d0f02df59bbef160df4c47c19414e5d76bd4ed 100644 --- a/adb/adb_client.cpp +++ b/adb/adb_client.cpp @@ -123,7 +123,7 @@ bool adb_status(int fd, std::string* error) { return false; } -int _adb_connect(const std::string& service, std::string* error) { +static int _adb_connect(const std::string& service, std::string* error) { D("_adb_connect: %s", service.c_str()); if (service.empty() || service.size() > MAX_PAYLOAD_V1) { *error = android::base::StringPrintf("bad service name length (%zd)", @@ -158,6 +158,25 @@ int _adb_connect(const std::string& service, std::string* error) { return fd; } +bool adb_kill_server() { + D("adb_kill_server"); + std::string reason; + int fd = socket_spec_connect(__adb_server_socket_spec, &reason); + if (fd < 0) { + fprintf(stderr, "cannot connect to daemon at %s: %s\n", __adb_server_socket_spec, + reason.c_str()); + return true; + } + + if (!SendProtocolString(fd, "host:kill")) { + fprintf(stderr, "error: write failure during connection: %s\n", strerror(errno)); + return false; + } + + ReadOrderlyShutdown(fd); + return true; +} + int adb_connect(const std::string& service, std::string* error) { // first query the adb server's version int fd = _adb_connect("host:version", error); @@ -214,18 +233,7 @@ int adb_connect(const std::string& service, std::string* error) { if (version != ADB_SERVER_VERSION) { fprintf(stderr, "adb server version (%d) doesn't match this client (%d); killing...\n", version, ADB_SERVER_VERSION); - fd = _adb_connect("host:kill", error); - if (fd >= 0) { - ReadOrderlyShutdown(fd); - adb_close(fd); - } else { - // If we couldn't connect to the server or had some other error, - // report it, but still try to start the server. - fprintf(stderr, "error: %s\n", error->c_str()); - } - - /* XXX can we better detect its death? */ - std::this_thread::sleep_for(2s); + adb_kill_server(); goto start_server; } } diff --git a/adb/adb_client.h b/adb/adb_client.h index d07c1e96bc1c886dd6e75e1fd5e64a0127fe0a43..fabec0050ffcf888f1b5d74e9ca3d0a2c404b4e3 100644 --- a/adb/adb_client.h +++ b/adb/adb_client.h @@ -26,7 +26,9 @@ // 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(const std::string& service, std::string* _Nonnull error); -int _adb_connect(const std::string& service, std::string* _Nonnull error); + +// Kill the currently running adb server, if it exists. +bool adb_kill_server(); // Connect to adb, connect to the named service, returns true if the connection // succeeded AND the service returned OKAY. Outputs any returned error otherwise. diff --git a/adb/commandline.cpp b/adb/commandline.cpp index a9b1540d5a20361126419764d868513a6042e44a..f49c69dafdc58161afbdfb5b4830b0a868dd8b52 100644 --- a/adb/commandline.cpp +++ b/adb/commandline.cpp @@ -1546,25 +1546,7 @@ int adb_commandline(int argc, const char** argv) { return 0; } else if (!strcmp(argv[0], "kill-server")) { - std::string error; - int fd = _adb_connect("host:kill", &error); - if (fd == -2) { - // Failed to make network connection to server. Don't output the - // network error since that is expected. - fprintf(stderr,"* server not running *\n"); - // Successful exit code because the server is already "killed". - return 0; - } else if (fd == -1) { - // Some other error. - fprintf(stderr, "error: %s\n", error.c_str()); - return 1; - } else { - // Successfully connected, kill command sent, okay status came back. - // Server should exit() in a moment, if not already. - ReadOrderlyShutdown(fd); - adb_close(fd); - return 0; - } + return adb_kill_server() ? 0 : 1; } else if (!strcmp(argv[0], "sideload")) { if (argc != 2) return syntax_error("sideload requires an argument");