Merge "metricsd: Add clang format config."
diff --git a/adb/adb_listeners.cpp b/adb/adb_listeners.cpp
index d5b1fd5..1b75090 100644
--- a/adb/adb_listeners.cpp
+++ b/adb/adb_listeners.cpp
@@ -33,21 +33,17 @@
};
static void ss_listener_event_func(int _fd, unsigned ev, void *_l) {
- asocket *s;
-
- if(ev & FDE_READ) {
+ if (ev & FDE_READ) {
struct sockaddr addr;
- socklen_t alen;
- int fd;
+ socklen_t alen = sizeof(addr);
+ int fd = adb_socket_accept(_fd, &addr, &alen);
+ if (fd < 0) return;
- alen = sizeof(addr);
- fd = adb_socket_accept(_fd, &addr, &alen);
- if(fd < 0) return;
+ int rcv_buf_size = CHUNK_SIZE;
+ adb_setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &rcv_buf_size, sizeof(rcv_buf_size));
- adb_socket_setbufsize(fd, CHUNK_SIZE);
-
- s = create_local_socket(fd);
- if(s) {
+ asocket* s = create_local_socket(fd);
+ if (s) {
connect_to_smartsocket(s);
return;
}
diff --git a/adb/file_sync_client.cpp b/adb/file_sync_client.cpp
index bd0e6c4..9ad7bad 100644
--- a/adb/file_sync_client.cpp
+++ b/adb/file_sync_client.cpp
@@ -103,7 +103,7 @@
// 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 @@
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,34 +163,37 @@
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;
- }
+ 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;
}
- sbuf.size = ret;
- if (!WriteFdExactly(fd, &sbuf, sizeof(unsigned) * 2 + ret)) {
- adb_close(lfd);
- return false;
+ sbuf.size = bytes_read;
+ WriteOrDie(lpath, rpath, &sbuf, sizeof(SyncRequest) + bytes_read);
+
+ total_bytes += bytes_read;
+ bytes_copied += bytes_read;
+
+ if (total_size == 0) {
+ // This case can happen if we're racing against something that wrote to the file
+ // between our stat and our read, or if we're reading a magic file that lies about
+ // its size.
+ Printf("%s: ?%%", rpath);
+ } else {
+ int percentage = static_cast<int>(bytes_copied * 100 / total_size);
+ Printf("%s: %d%%", rpath, percentage);
}
- total_bytes += ret;
-
- bytes_copied += ret;
-
- int percentage = static_cast<int>(bytes_copied * 100 / total_size);
- Printf("%s: %d%%", rpath, percentage);
}
adb_close(lfd);
@@ -199,12 +201,7 @@
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 +294,27 @@
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 +380,9 @@
}
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 +403,8 @@
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 {
@@ -458,8 +479,14 @@
bytes_copied += msg.data.size;
- int percentage = static_cast<int>(bytes_copied * 100 / size);
- sc.Printf("%s: %d%%", rpath, percentage);
+ if (size == 0) {
+ // This case can happen if we're racing against something that wrote to the file between
+ // our stat and our read, or if we're reading a magic file that lies about its size.
+ sc.Printf("%s: ?%%", rpath);
+ } else {
+ int percentage = static_cast<int>(bytes_copied * 100 / size);
+ sc.Printf("%s: %d%%", rpath, percentage);
+ }
}
adb_close(lfd);
diff --git a/adb/file_sync_service.cpp b/adb/file_sync_service.cpp
index 7484a7c..945fa5a 100644
--- a/adb/file_sync_service.cpp
+++ b/adb/file_sync_service.cpp
@@ -394,6 +394,18 @@
void file_sync_service(int fd, void* cookie) {
std::vector<char> buffer(SYNC_DATA_MAX);
+ // If there's a problem on the device, we'll send an ID_FAIL message and
+ // close the socket. Unfortunately the kernel will sometimes throw that
+ // data away if the other end keeps writing without reading (which is
+ // the normal case with our protocol --- they won't read until the end).
+ // So set SO_LINGER to give the client 20s to get around to reading our
+ // failure response. Without this, the other side's ability to report
+ // useful errors is reduced.
+ struct linger l;
+ l.l_onoff = 1;
+ l.l_linger = 20;
+ adb_setsockopt(fd, SOL_SOCKET, SO_LINGER, &l, sizeof(l));
+
while (handle_sync_command(fd, buffer)) {
}
diff --git a/adb/sysdeps.h b/adb/sysdeps.h
index cba66fc..22c9b39 100644
--- a/adb/sysdeps.h
+++ b/adb/sysdeps.h
@@ -242,18 +242,6 @@
#undef setsockopt
#define setsockopt ___xxx_setsockopt
-static __inline__ int adb_socket_setbufsize( int fd, int bufsize )
-{
- int opt = bufsize;
- return adb_setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (const void*)&opt, sizeof(opt));
-}
-
-static __inline__ void disable_tcp_nagle( int fd )
-{
- int on = 1;
- adb_setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (const void*)&on, sizeof(on));
-}
-
extern int adb_socketpair( int sv[2] );
static __inline__ int adb_is_absolute_host_path(const char* path) {
@@ -670,18 +658,6 @@
#endif
}
-static __inline__ int adb_socket_setbufsize(int fd, int bufsize )
-{
- int opt = bufsize;
- return setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &opt, sizeof(opt));
-}
-
-static __inline__ void disable_tcp_nagle(int fd)
-{
- int on = 1;
- setsockopt( fd, IPPROTO_TCP, TCP_NODELAY, (void*)&on, sizeof(on) );
-}
-
static __inline__ int adb_setsockopt( int fd, int level, int optname, const void* optval, socklen_t optlen )
{
return setsockopt( fd, level, optname, optval, optlen );
@@ -739,4 +715,9 @@
#endif /* !_WIN32 */
+static inline void disable_tcp_nagle(int fd) {
+ int off = 1;
+ adb_setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &off, sizeof(off));
+}
+
#endif /* _ADB_SYSDEPS_H */