2015-05-07 01:13:42 +02:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2015 The Android Open Source Project
|
|
|
|
*
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
|
|
|
*
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
|
|
|
*/
|
|
|
|
|
2009-03-04 04:32:55 +01:00
|
|
|
#include "sysdeps.h"
|
2015-05-07 01:13:42 +02:00
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
2015-12-05 07:00:26 +01:00
|
|
|
#include <android-base/file.h>
|
|
|
|
#include <android-base/logging.h>
|
|
|
|
#include <android-base/strings.h>
|
2015-07-24 02:12:58 +02:00
|
|
|
#include <cutils/sockets.h>
|
2015-05-07 01:13:42 +02:00
|
|
|
|
2009-03-04 04:32:55 +01:00
|
|
|
#include "adb.h"
|
|
|
|
#include "adb_client.h"
|
adb: fix adb client running out of sockets on Windows
Background
==========
On Windows, if you run "adb shell exit" in a loop in two windows,
eventually the adb client will be unable to connect to the adb server. I
think connect() is returning WSAEADDRINUSE: "Only one usage of each
socket address (protocol/network address/port) is normally permitted.
(10048)". The Windows System Event Log may also show Event 4227, Tcpip.
Netstat output is filled with:
# for the adb server
TCP 127.0.0.1:5037 127.0.0.1:65523 TIME_WAIT
# for the adb client
TCP 127.0.0.1:65523 127.0.0.1:5037 TIME_WAIT
The error probably means that the client is running out of free
address:port pairs.
The first netstat line is unavoidable, but the second line exists
because the adb client is not waiting for orderly/graceful shutdown of
the socket, and that is apparently required on Windows to get rid of the
second line. For more info, see
https://github.com/CompareAndSwap/SocketCloseTest .
This is exacerbated by the fact that "adb shell exit" makes 4 socket
connections to the adb server: 1) host:version, 2) host:features, 3)
host:version (again), 4) shell:exit. Also exacerbating is the fact that
the adb protocol is length-prefixed so the client typically does not
have to 'read() until zero' which effectively waits for orderly/graceful
shutdown.
The Fix
=======
Introduce a function, ReadOrderlyShutdown(), that should be called in
the adb client to wait for the server to close its socket, before
closing the client socket.
I reviewed all code where the adb client makes a connection to the adb
server and added ReadOrderlyShutdown() when it made sense. I wasn't able
to add it to the following:
* interactive_shell: this doesn't matter because this is interactive and
thus can't be run fast enough to use up ports.
* adb sideload: I couldn't get enough test coverage and I don't think
this is being called frequently enough to be a problem.
* send_shell_command, backup, adb_connect_command, adb shell, adb
exec-out, install_multiple_app, adb_send_emulator_command: These
already wait for server socket shutdown since they already call
recv() until zero.
* restore, adb exec-in: protocol design can't have the server close
first.
* adb start-server: no fd is actually returned
* create_local_service_socket, local_connect_arbitrary_ports,
connect_device: probably called rarely enough not to be a problem.
Also in this change
===================
* Clarify comments in when adb_shutdown() is called before exit().
* add some missing adb_close() in adb sideload.
* Fixup error handling and comments in adb_send_emulator_command().
* Make SyncConnection::SendQuit return a success boolean.
* Add unittest for adb emu kill command. This gets code coverage over
this very careful piece of code.
Change-Id: Iad0b1336f5b74186af2cd35f7ea827d0fa77a17c
Signed-off-by: Spencer Low <CompareAndSwap@gmail.com>
2015-10-15 02:32:44 +02:00
|
|
|
#include "adb_io.h"
|
2016-05-26 00:17:10 +02:00
|
|
|
#include "adb_utils.h"
|
|
|
|
|
|
|
|
// Return the console authentication command for the emulator, if needed
|
|
|
|
static std::string adb_construct_auth_command() {
|
|
|
|
static const char auth_token_filename[] = ".emulator_console_auth_token";
|
|
|
|
|
2016-08-31 00:23:35 +02:00
|
|
|
std::string auth_token_path = adb_get_homedir_path();
|
2016-05-26 00:17:10 +02:00
|
|
|
auth_token_path += OS_PATH_SEPARATOR;
|
|
|
|
auth_token_path += auth_token_filename;
|
|
|
|
|
|
|
|
// read the token
|
|
|
|
std::string token;
|
|
|
|
if (!android::base::ReadFileToString(auth_token_path, &token)
|
|
|
|
|| token.empty()) {
|
|
|
|
// we either can't read the file, or it doesn't exist, or it's empty -
|
|
|
|
// either way we won't add any authentication command.
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
|
|
|
|
// now construct and return the actual command: "auth <token>\n"
|
|
|
|
std::string command = "auth ";
|
|
|
|
command += token;
|
|
|
|
command += '\n';
|
|
|
|
return command;
|
|
|
|
}
|
2009-03-04 04:32:55 +01:00
|
|
|
|
2015-05-07 01:13:42 +02:00
|
|
|
// Return the console port of the currently connected emulator (if any) or -1 if
|
|
|
|
// there is no emulator, and -2 if there is more than one.
|
|
|
|
static int adb_get_emulator_console_port(const char* serial) {
|
|
|
|
if (serial) {
|
|
|
|
// The user specified a serial number; is it an emulator?
|
|
|
|
int port;
|
|
|
|
return (sscanf(serial, "emulator-%d", &port) == 1) ? port : -1;
|
|
|
|
}
|
2009-03-04 04:32:55 +01:00
|
|
|
|
2015-05-07 01:13:42 +02:00
|
|
|
// No specific device was given, so get the list of connected devices and
|
|
|
|
// search for emulators. If there's one, we'll take it. If there are more
|
|
|
|
// than one, that's an error.
|
|
|
|
std::string devices;
|
|
|
|
std::string error;
|
|
|
|
if (!adb_query("host:devices", &devices, &error)) {
|
|
|
|
fprintf(stderr, "error: no emulator connected: %s\n", error.c_str());
|
2009-03-04 04:32:55 +01:00
|
|
|
return -1;
|
|
|
|
}
|
2015-05-07 01:13:42 +02:00
|
|
|
|
|
|
|
int port;
|
|
|
|
size_t emulator_count = 0;
|
|
|
|
for (const auto& device : android::base::Split(devices, "\n")) {
|
|
|
|
if (sscanf(device.c_str(), "emulator-%d", &port) == 1) {
|
|
|
|
if (++emulator_count > 1) {
|
|
|
|
fprintf(
|
|
|
|
stderr, "error: more than one emulator detected; use -s\n");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (emulator_count == 0) {
|
|
|
|
fprintf(stderr, "error: no emulator detected\n");
|
2009-03-04 04:32:55 +01:00
|
|
|
return -1;
|
|
|
|
}
|
2015-05-07 01:13:42 +02:00
|
|
|
|
|
|
|
return port;
|
2009-03-04 04:32:55 +01:00
|
|
|
}
|
|
|
|
|
2015-05-07 01:13:42 +02:00
|
|
|
static int connect_to_console(const char* serial) {
|
|
|
|
int port = adb_get_emulator_console_port(serial);
|
|
|
|
if (port == -1) {
|
|
|
|
return -1;
|
|
|
|
}
|
2009-03-04 04:32:55 +01:00
|
|
|
|
2015-07-31 08:07:55 +02:00
|
|
|
std::string error;
|
|
|
|
int fd = network_loopback_client(port, SOCK_STREAM, &error);
|
2015-05-07 01:13:42 +02:00
|
|
|
if (fd == -1) {
|
2015-07-31 08:07:55 +02:00
|
|
|
fprintf(stderr, "error: could not connect to TCP port %d: %s\n", port,
|
|
|
|
error.c_str());
|
2015-05-07 01:13:42 +02:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
return fd;
|
|
|
|
}
|
2009-03-04 04:32:55 +01:00
|
|
|
|
2015-05-07 01:13:42 +02:00
|
|
|
int adb_send_emulator_command(int argc, const char** argv, const char* serial) {
|
|
|
|
int fd = connect_to_console(serial);
|
|
|
|
if (fd == -1) {
|
2009-03-04 04:32:55 +01:00
|
|
|
return 1;
|
2015-05-07 01:13:42 +02:00
|
|
|
}
|
2009-03-04 04:32:55 +01:00
|
|
|
|
2016-05-26 00:17:10 +02:00
|
|
|
std::string commands = adb_construct_auth_command();
|
adb: fix adb client running out of sockets on Windows
Background
==========
On Windows, if you run "adb shell exit" in a loop in two windows,
eventually the adb client will be unable to connect to the adb server. I
think connect() is returning WSAEADDRINUSE: "Only one usage of each
socket address (protocol/network address/port) is normally permitted.
(10048)". The Windows System Event Log may also show Event 4227, Tcpip.
Netstat output is filled with:
# for the adb server
TCP 127.0.0.1:5037 127.0.0.1:65523 TIME_WAIT
# for the adb client
TCP 127.0.0.1:65523 127.0.0.1:5037 TIME_WAIT
The error probably means that the client is running out of free
address:port pairs.
The first netstat line is unavoidable, but the second line exists
because the adb client is not waiting for orderly/graceful shutdown of
the socket, and that is apparently required on Windows to get rid of the
second line. For more info, see
https://github.com/CompareAndSwap/SocketCloseTest .
This is exacerbated by the fact that "adb shell exit" makes 4 socket
connections to the adb server: 1) host:version, 2) host:features, 3)
host:version (again), 4) shell:exit. Also exacerbating is the fact that
the adb protocol is length-prefixed so the client typically does not
have to 'read() until zero' which effectively waits for orderly/graceful
shutdown.
The Fix
=======
Introduce a function, ReadOrderlyShutdown(), that should be called in
the adb client to wait for the server to close its socket, before
closing the client socket.
I reviewed all code where the adb client makes a connection to the adb
server and added ReadOrderlyShutdown() when it made sense. I wasn't able
to add it to the following:
* interactive_shell: this doesn't matter because this is interactive and
thus can't be run fast enough to use up ports.
* adb sideload: I couldn't get enough test coverage and I don't think
this is being called frequently enough to be a problem.
* send_shell_command, backup, adb_connect_command, adb shell, adb
exec-out, install_multiple_app, adb_send_emulator_command: These
already wait for server socket shutdown since they already call
recv() until zero.
* restore, adb exec-in: protocol design can't have the server close
first.
* adb start-server: no fd is actually returned
* create_local_service_socket, local_connect_arbitrary_ports,
connect_device: probably called rarely enough not to be a problem.
Also in this change
===================
* Clarify comments in when adb_shutdown() is called before exit().
* add some missing adb_close() in adb sideload.
* Fixup error handling and comments in adb_send_emulator_command().
* Make SyncConnection::SendQuit return a success boolean.
* Add unittest for adb emu kill command. This gets code coverage over
this very careful piece of code.
Change-Id: Iad0b1336f5b74186af2cd35f7ea827d0fa77a17c
Signed-off-by: Spencer Low <CompareAndSwap@gmail.com>
2015-10-15 02:32:44 +02:00
|
|
|
|
2015-05-07 01:13:42 +02:00
|
|
|
for (int i = 1; i < argc; i++) {
|
adb: fix adb client running out of sockets on Windows
Background
==========
On Windows, if you run "adb shell exit" in a loop in two windows,
eventually the adb client will be unable to connect to the adb server. I
think connect() is returning WSAEADDRINUSE: "Only one usage of each
socket address (protocol/network address/port) is normally permitted.
(10048)". The Windows System Event Log may also show Event 4227, Tcpip.
Netstat output is filled with:
# for the adb server
TCP 127.0.0.1:5037 127.0.0.1:65523 TIME_WAIT
# for the adb client
TCP 127.0.0.1:65523 127.0.0.1:5037 TIME_WAIT
The error probably means that the client is running out of free
address:port pairs.
The first netstat line is unavoidable, but the second line exists
because the adb client is not waiting for orderly/graceful shutdown of
the socket, and that is apparently required on Windows to get rid of the
second line. For more info, see
https://github.com/CompareAndSwap/SocketCloseTest .
This is exacerbated by the fact that "adb shell exit" makes 4 socket
connections to the adb server: 1) host:version, 2) host:features, 3)
host:version (again), 4) shell:exit. Also exacerbating is the fact that
the adb protocol is length-prefixed so the client typically does not
have to 'read() until zero' which effectively waits for orderly/graceful
shutdown.
The Fix
=======
Introduce a function, ReadOrderlyShutdown(), that should be called in
the adb client to wait for the server to close its socket, before
closing the client socket.
I reviewed all code where the adb client makes a connection to the adb
server and added ReadOrderlyShutdown() when it made sense. I wasn't able
to add it to the following:
* interactive_shell: this doesn't matter because this is interactive and
thus can't be run fast enough to use up ports.
* adb sideload: I couldn't get enough test coverage and I don't think
this is being called frequently enough to be a problem.
* send_shell_command, backup, adb_connect_command, adb shell, adb
exec-out, install_multiple_app, adb_send_emulator_command: These
already wait for server socket shutdown since they already call
recv() until zero.
* restore, adb exec-in: protocol design can't have the server close
first.
* adb start-server: no fd is actually returned
* create_local_service_socket, local_connect_arbitrary_ports,
connect_device: probably called rarely enough not to be a problem.
Also in this change
===================
* Clarify comments in when adb_shutdown() is called before exit().
* add some missing adb_close() in adb sideload.
* Fixup error handling and comments in adb_send_emulator_command().
* Make SyncConnection::SendQuit return a success boolean.
* Add unittest for adb emu kill command. This gets code coverage over
this very careful piece of code.
Change-Id: Iad0b1336f5b74186af2cd35f7ea827d0fa77a17c
Signed-off-by: Spencer Low <CompareAndSwap@gmail.com>
2015-10-15 02:32:44 +02:00
|
|
|
commands.append(argv[i]);
|
2016-05-26 00:17:10 +02:00
|
|
|
commands.push_back(i == argc - 1 ? '\n' : ' ');
|
2015-05-07 01:13:42 +02:00
|
|
|
}
|
2009-03-04 04:32:55 +01:00
|
|
|
|
adb: fix adb client running out of sockets on Windows
Background
==========
On Windows, if you run "adb shell exit" in a loop in two windows,
eventually the adb client will be unable to connect to the adb server. I
think connect() is returning WSAEADDRINUSE: "Only one usage of each
socket address (protocol/network address/port) is normally permitted.
(10048)". The Windows System Event Log may also show Event 4227, Tcpip.
Netstat output is filled with:
# for the adb server
TCP 127.0.0.1:5037 127.0.0.1:65523 TIME_WAIT
# for the adb client
TCP 127.0.0.1:65523 127.0.0.1:5037 TIME_WAIT
The error probably means that the client is running out of free
address:port pairs.
The first netstat line is unavoidable, but the second line exists
because the adb client is not waiting for orderly/graceful shutdown of
the socket, and that is apparently required on Windows to get rid of the
second line. For more info, see
https://github.com/CompareAndSwap/SocketCloseTest .
This is exacerbated by the fact that "adb shell exit" makes 4 socket
connections to the adb server: 1) host:version, 2) host:features, 3)
host:version (again), 4) shell:exit. Also exacerbating is the fact that
the adb protocol is length-prefixed so the client typically does not
have to 'read() until zero' which effectively waits for orderly/graceful
shutdown.
The Fix
=======
Introduce a function, ReadOrderlyShutdown(), that should be called in
the adb client to wait for the server to close its socket, before
closing the client socket.
I reviewed all code where the adb client makes a connection to the adb
server and added ReadOrderlyShutdown() when it made sense. I wasn't able
to add it to the following:
* interactive_shell: this doesn't matter because this is interactive and
thus can't be run fast enough to use up ports.
* adb sideload: I couldn't get enough test coverage and I don't think
this is being called frequently enough to be a problem.
* send_shell_command, backup, adb_connect_command, adb shell, adb
exec-out, install_multiple_app, adb_send_emulator_command: These
already wait for server socket shutdown since they already call
recv() until zero.
* restore, adb exec-in: protocol design can't have the server close
first.
* adb start-server: no fd is actually returned
* create_local_service_socket, local_connect_arbitrary_ports,
connect_device: probably called rarely enough not to be a problem.
Also in this change
===================
* Clarify comments in when adb_shutdown() is called before exit().
* add some missing adb_close() in adb sideload.
* Fixup error handling and comments in adb_send_emulator_command().
* Make SyncConnection::SendQuit return a success boolean.
* Add unittest for adb emu kill command. This gets code coverage over
this very careful piece of code.
Change-Id: Iad0b1336f5b74186af2cd35f7ea827d0fa77a17c
Signed-off-by: Spencer Low <CompareAndSwap@gmail.com>
2015-10-15 02:32:44 +02:00
|
|
|
commands.append("quit\n");
|
|
|
|
|
|
|
|
if (!WriteFdExactly(fd, commands)) {
|
|
|
|
fprintf(stderr, "error: cannot write to emulator: %s\n",
|
|
|
|
strerror(errno));
|
|
|
|
adb_close(fd);
|
|
|
|
return 1;
|
2009-03-04 04:32:55 +01:00
|
|
|
}
|
2015-05-07 01:13:42 +02:00
|
|
|
|
|
|
|
// Drain output that the emulator console has sent us to prevent a problem
|
|
|
|
// on Windows where if adb closes the socket without reading all the data,
|
|
|
|
// the emulator's next call to recv() will have an ECONNABORTED error,
|
|
|
|
// preventing the emulator from reading the command that adb has sent.
|
|
|
|
// https://code.google.com/p/android/issues/detail?id=21021
|
|
|
|
int result;
|
2018-10-26 16:11:55 +02:00
|
|
|
std::string emulator_output;
|
2015-05-07 01:13:42 +02:00
|
|
|
do {
|
|
|
|
char buf[BUFSIZ];
|
|
|
|
result = adb_read(fd, buf, sizeof(buf));
|
adb: fix adb client running out of sockets on Windows
Background
==========
On Windows, if you run "adb shell exit" in a loop in two windows,
eventually the adb client will be unable to connect to the adb server. I
think connect() is returning WSAEADDRINUSE: "Only one usage of each
socket address (protocol/network address/port) is normally permitted.
(10048)". The Windows System Event Log may also show Event 4227, Tcpip.
Netstat output is filled with:
# for the adb server
TCP 127.0.0.1:5037 127.0.0.1:65523 TIME_WAIT
# for the adb client
TCP 127.0.0.1:65523 127.0.0.1:5037 TIME_WAIT
The error probably means that the client is running out of free
address:port pairs.
The first netstat line is unavoidable, but the second line exists
because the adb client is not waiting for orderly/graceful shutdown of
the socket, and that is apparently required on Windows to get rid of the
second line. For more info, see
https://github.com/CompareAndSwap/SocketCloseTest .
This is exacerbated by the fact that "adb shell exit" makes 4 socket
connections to the adb server: 1) host:version, 2) host:features, 3)
host:version (again), 4) shell:exit. Also exacerbating is the fact that
the adb protocol is length-prefixed so the client typically does not
have to 'read() until zero' which effectively waits for orderly/graceful
shutdown.
The Fix
=======
Introduce a function, ReadOrderlyShutdown(), that should be called in
the adb client to wait for the server to close its socket, before
closing the client socket.
I reviewed all code where the adb client makes a connection to the adb
server and added ReadOrderlyShutdown() when it made sense. I wasn't able
to add it to the following:
* interactive_shell: this doesn't matter because this is interactive and
thus can't be run fast enough to use up ports.
* adb sideload: I couldn't get enough test coverage and I don't think
this is being called frequently enough to be a problem.
* send_shell_command, backup, adb_connect_command, adb shell, adb
exec-out, install_multiple_app, adb_send_emulator_command: These
already wait for server socket shutdown since they already call
recv() until zero.
* restore, adb exec-in: protocol design can't have the server close
first.
* adb start-server: no fd is actually returned
* create_local_service_socket, local_connect_arbitrary_ports,
connect_device: probably called rarely enough not to be a problem.
Also in this change
===================
* Clarify comments in when adb_shutdown() is called before exit().
* add some missing adb_close() in adb sideload.
* Fixup error handling and comments in adb_send_emulator_command().
* Make SyncConnection::SendQuit return a success boolean.
* Add unittest for adb emu kill command. This gets code coverage over
this very careful piece of code.
Change-Id: Iad0b1336f5b74186af2cd35f7ea827d0fa77a17c
Signed-off-by: Spencer Low <CompareAndSwap@gmail.com>
2015-10-15 02:32:44 +02:00
|
|
|
// Keep reading until zero bytes (orderly/graceful shutdown) or an
|
|
|
|
// error. If 'adb emu kill' is executed, the emulator calls exit() with
|
|
|
|
// the socket open (and shutdown(SD_SEND) was not called), which causes
|
|
|
|
// Windows to send a TCP RST segment which causes adb to get ECONNRESET.
|
|
|
|
// Any other emu command is followed by the quit command that we
|
|
|
|
// appended above, and that causes the emulator to close the socket
|
|
|
|
// which should cause zero bytes (orderly/graceful shutdown) to be
|
|
|
|
// returned.
|
2018-10-26 16:11:55 +02:00
|
|
|
if (result > 0) emulator_output.append(buf, result);
|
2015-05-07 01:13:42 +02:00
|
|
|
} while (result > 0);
|
|
|
|
|
2018-10-26 16:11:55 +02:00
|
|
|
// Note: the following messages are expected to be quite stable from emulator.
|
|
|
|
//
|
|
|
|
// Emulator console will send the following message upon connection:
|
|
|
|
//
|
|
|
|
// Android Console: Authentication required
|
|
|
|
// Android Console: type 'auth <auth_token>' to authenticate
|
|
|
|
// Android Console: you can find your <auth_token> in
|
|
|
|
// '/<path-to-home>/.emulator_console_auth_token'
|
|
|
|
// OK\r\n
|
|
|
|
//
|
|
|
|
// and the following after authentication:
|
|
|
|
// Android Console: type 'help' for a list of commands
|
|
|
|
// OK\r\n
|
|
|
|
//
|
|
|
|
// So try search and skip first two "OK\r\n", print the rest.
|
|
|
|
//
|
|
|
|
const std::string delims = "OK\r\n";
|
|
|
|
size_t found = 0;
|
|
|
|
for (int i = 0; i < 2; ++i) {
|
|
|
|
const size_t result = emulator_output.find(delims, found);
|
|
|
|
if (result == std::string::npos) {
|
|
|
|
break;
|
|
|
|
} else {
|
|
|
|
found = result + delims.size();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
printf("%s", emulator_output.c_str() + found);
|
2009-03-04 04:32:55 +01:00
|
|
|
adb_close(fd);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|