summaryrefslogtreecommitdiff
path: root/adb/file_sync_client.cpp
diff options
context:
space:
mode:
authorElliott Hughes <enh@google.com>2015-11-20 22:01:06 -0800
committerElliott Hughes <enh@google.com>2015-11-20 22:01:06 -0800
commitcc65c3b9f8edc6fb48ffe725376e65fac42851d6 (patch)
treed2e5939de458d3257d172deaa5da9279fb8915f5 /adb/file_sync_client.cpp
parentddf41f1ad0bc5fbe4a09fbcfde74492a51a705cf (diff)
Fix "adb sync" (and "adb push") error reporting.
This patch ensures that we read any error response from the server if the server closes the connection. Unfortunately, that's not sufficient to ensure that we always see the server's error message --- sometimes the data just gets thrown away because we keep writing without reading. Setting SO_LINGER avoids this. Bug: http://b/25230872 Change-Id: I96c019cc72bd139198de79bf29e6536cc462c20f
Diffstat (limited to 'adb/file_sync_client.cpp')
-rw-r--r--adb/file_sync_client.cpp66
1 files changed, 40 insertions, 26 deletions
diff --git a/adb/file_sync_client.cpp b/adb/file_sync_client.cpp
index e109e3eef4..634177b311 100644
--- a/adb/file_sync_client.cpp
+++ b/adb/file_sync_client.cpp
@@ -103,7 +103,7 @@ class SyncConnection {
// Sending header, payload, and footer in a single write makes a huge
// difference to "adb sync" performance.
bool SendSmallFile(const char* path_and_mode,
- const char* rpath,
+ const char* lpath, const char* rpath,
unsigned mtime,
const char* data, size_t data_length) {
Print(rpath);
@@ -139,8 +139,7 @@ class SyncConnection {
req_done->path_length = mtime;
p += sizeof(SyncRequest);
- if (!WriteFdExactly(fd, &buf[0], (p - &buf[0]))) return false;
-
+ WriteOrDie(lpath, rpath, &buf[0], (p - &buf[0]));
total_bytes += data_length;
return true;
}
@@ -164,31 +163,27 @@ class SyncConnection {
int lfd = adb_open(lpath, O_RDONLY);
if (lfd < 0) {
- Error("cannot open '%s': %s", lpath, strerror(errno));
+ Error("opening '%s' locally failed: %s", lpath, strerror(errno));
return false;
}
syncsendbuf sbuf;
sbuf.id = ID_DATA;
while (true) {
- int ret = adb_read(lfd, sbuf.data, max);
- if (ret <= 0) {
- if (ret < 0) {
- Error("cannot read '%s': %s", lpath, strerror(errno));
- adb_close(lfd);
- return false;
- }
- break;
- }
-
- sbuf.size = ret;
- if (!WriteFdExactly(fd, &sbuf, sizeof(unsigned) * 2 + ret)) {
+ int bytes_read = adb_read(lfd, sbuf.data, max);
+ if (bytes_read == -1) {
+ Error("reading '%s' locally failed: %s", lpath, strerror(errno));
adb_close(lfd);
return false;
+ } else if (bytes_read == 0) {
+ break;
}
- total_bytes += ret;
- bytes_copied += ret;
+ sbuf.size = bytes_read;
+ WriteOrDie(lpath, rpath, &sbuf, sizeof(SyncRequest) + bytes_read);
+
+ total_bytes += bytes_read;
+ bytes_copied += bytes_read;
int percentage = static_cast<int>(bytes_copied * 100 / total_size);
Printf("%s: %d%%", rpath, percentage);
@@ -199,12 +194,7 @@ class SyncConnection {
syncmsg msg;
msg.data.id = ID_DONE;
msg.data.size = mtime;
- if (!WriteFdExactly(fd, &msg.data, sizeof(msg.data))) {
- Error("failed to send ID_DONE message for '%s': %s", rpath, strerror(errno));
- return false;
- }
-
- return true;
+ return WriteOrDie(lpath, rpath, &msg.data, sizeof(msg.data));
}
bool CopyDone(const char* from, const char* to) {
@@ -297,6 +287,27 @@ class SyncConnection {
return SendRequest(ID_QUIT, ""); // TODO: add a SendResponse?
}
+ bool WriteOrDie(const char* from, const char* to, const void* data, size_t data_length) {
+ if (!WriteFdExactly(fd, data, data_length)) {
+ if (errno == ECONNRESET) {
+ // Assume adbd told us why it was closing the connection, and
+ // try to read failure reason from adbd.
+ syncmsg msg;
+ if (!ReadFdExactly(fd, &msg.status, sizeof(msg.status))) {
+ Error("failed to copy '%s' to '%s': no response: %s", from, to, strerror(errno));
+ } else if (msg.status.id != ID_FAIL) {
+ Error("failed to copy '%s' to '%s': not ID_FAIL: %d", from, to, msg.status.id);
+ } else {
+ ReportCopyFailure(from, to, msg);
+ }
+ } else {
+ Error("%zu-byte write failed: %s", data_length, strerror(errno));
+ }
+ _exit(1);
+ }
+ return true;
+ }
+
static uint64_t CurrentTimeMs() {
struct timeval tv;
gettimeofday(&tv, 0); // (Not clock_gettime because of Mac/Windows.)
@@ -362,7 +373,9 @@ static bool sync_send(SyncConnection& sc, const char* lpath, const char* rpath,
}
buf[data_length++] = '\0';
- if (!sc.SendSmallFile(path_and_mode.c_str(), rpath, mtime, buf, data_length)) return false;
+ if (!sc.SendSmallFile(path_and_mode.c_str(), lpath, rpath, mtime, buf, data_length)) {
+ return false;
+ }
return sc.CopyDone(lpath, rpath);
#endif
}
@@ -383,7 +396,8 @@ static bool sync_send(SyncConnection& sc, const char* lpath, const char* rpath,
sc.Error("failed to read all of '%s': %s", lpath, strerror(errno));
return false;
}
- if (!sc.SendSmallFile(path_and_mode.c_str(), rpath, mtime, data.data(), data.size())) {
+ if (!sc.SendSmallFile(path_and_mode.c_str(), lpath, rpath, mtime,
+ data.data(), data.size())) {
return false;
}
} else {