adb: report error in copy_to_file.

Previously, if we failed to read a file after successfully opening it,
(e.g. because it's a directory), we would return prematurely without
notifying our caller, which would then wait forever for a response that
isn't coming.

Switch all of the adb install callsites over to checking the result,
but leave the other callsites ignoring the result, because they're
either deprecated, or don't care.

Bug: http://b/145621968
Test: mkdir foo.apk; adb install foo.apk
Change-Id: Ia82f8280b144f7881e067a10cd17f9a89019cf3f
This commit is contained in:
Josh Gao 2019-12-03 16:05:54 -08:00
parent 2e10d8f74f
commit 3828ebcdd8
3 changed files with 27 additions and 11 deletions

View file

@ -227,16 +227,20 @@ static int install_app_streamed(int argc, const char** argv, bool use_fastdeploy
return 1;
}
copy_to_file(local_fd.get(), remote_fd.get());
if (!copy_to_file(local_fd.get(), remote_fd.get())) {
fprintf(stderr, "adb: failed to install: copy_to_file: %s: %s", file, strerror(errno));
return 1;
}
char buf[BUFSIZ];
read_status_line(remote_fd.get(), buf, sizeof(buf));
if (!strncmp("Success", buf, 7)) {
fputs(buf, stdout);
return 0;
if (strncmp("Success", buf, 7) != 0) {
fprintf(stderr, "adb: failed to install %s: %s", file, buf);
return 1;
}
fprintf(stderr, "adb: failed to install %s: %s", file, buf);
return 1;
fputs(buf, stdout);
return 0;
}
static int install_app_legacy(int argc, const char** argv, bool use_fastdeploy) {
@ -455,7 +459,12 @@ int install_multiple_app(int argc, const char** argv) {
goto finalize_session;
}
copy_to_file(local_fd.get(), remote_fd.get());
if (!copy_to_file(local_fd.get(), remote_fd.get())) {
fprintf(stderr, "adb: failed to write \"%s\": %s\n", file, strerror(errno));
success = false;
goto finalize_session;
}
read_status_line(remote_fd.get(), buf, sizeof(buf));
if (strncmp("Success", buf, 7)) {
@ -634,7 +643,11 @@ int install_multi_package(int argc, const char** argv) {
goto finalize_multi_package_session;
}
copy_to_file(local_fd.get(), remote_fd.get());
if (!copy_to_file(local_fd.get(), remote_fd.get())) {
fprintf(stderr, "adb: failed to write %s: %s\n", split.c_str(), strerror(errno));
goto finalize_multi_package_session;
}
read_status_line(remote_fd.get(), buf, sizeof(buf));
if (strncmp("Success", buf, 7)) {

View file

@ -352,7 +352,8 @@ static void stdinout_raw_epilogue(int inFd, int outFd, int old_stdin_mode, int o
#endif
}
void copy_to_file(int inFd, int outFd) {
bool copy_to_file(int inFd, int outFd) {
bool result = true;
std::vector<char> buf(64 * 1024);
int len;
long total = 0;
@ -375,6 +376,7 @@ void copy_to_file(int inFd, int outFd) {
}
if (len < 0) {
D("copy_to_file(): read failed: %s", strerror(errno));
result = false;
break;
}
if (outFd == STDOUT_FILENO) {
@ -388,7 +390,8 @@ void copy_to_file(int inFd, int outFd) {
stdinout_raw_epilogue(inFd, outFd, old_stdin_mode, old_stdout_mode);
D("copy_to_file() finished after %lu bytes", total);
D("copy_to_file() finished with %s after %lu bytes", result ? "success" : "failure", total);
return result;
}
static void send_window_size_change(int fd, std::unique_ptr<ShellProtocol>& shell) {

View file

@ -100,7 +100,7 @@ extern DefaultStandardStreamsCallback DEFAULT_STANDARD_STREAMS_CALLBACK;
int adb_commandline(int argc, const char** argv);
void copy_to_file(int inFd, int outFd);
bool copy_to_file(int inFd, int outFd);
// Connects to the device "shell" service with |command| and prints the
// resulting output.