Loading adb/Android.mk +3 −2 Original line number Diff line number Diff line Loading @@ -213,12 +213,13 @@ LOCAL_STATIC_LIBRARIES_windows := AdbWinApi LOCAL_REQUIRED_MODULES_windows := AdbWinApi AdbWinUsbApi LOCAL_SRC_FILES := \ adb_client.cpp \ client/main.cpp \ console.cpp \ commandline.cpp \ adb_client.cpp \ services.cpp \ file_sync_client.cpp \ line_printer.cpp \ services.cpp \ shell_service_protocol.cpp \ LOCAL_CFLAGS += \ Loading adb/commandline.cpp +10 −15 Original line number Diff line number Diff line Loading @@ -101,12 +101,10 @@ static void help() { " will disconnect from all connected TCP/IP devices.\n" "\n" "device commands:\n" " adb push [-p] <local> <remote>\n" " adb push <local> <remote>\n" " - copy file/dir to device\n" " ('-p' to display the transfer progress)\n" " adb pull [-p] [-a] <remote> [<local>]\n" " adb pull [-a] <remote> [<local>]\n" " - copy file/dir from device\n" " ('-p' to display the transfer progress)\n" " ('-a' means copy timestamp and mode)\n" " adb sync [ <directory> ] - copy host->device only if changed\n" " (-l means list but don't copy)\n" Loading Loading @@ -1065,15 +1063,14 @@ static std::string find_product_out_path(const std::string& hint) { return path; } static void parse_push_pull_args(const char **arg, int narg, char const **path1, char const **path2, bool* show_progress, static void parse_push_pull_args(const char **arg, int narg, char const **path1, char const **path2, int *copy_attrs) { *show_progress = false; *copy_attrs = 0; while (narg > 0) { if (!strcmp(*arg, "-p")) { *show_progress = true; // Silently ignore for backwards compatibility. } else if (!strcmp(*arg, "-a")) { *copy_attrs = 1; } else { Loading Loading @@ -1561,22 +1558,20 @@ int adb_commandline(int argc, const char **argv) { return do_sync_ls(argv[1]) ? 0 : 1; } else if (!strcmp(argv[0], "push")) { bool show_progress = false; int copy_attrs = 0; const char* lpath = NULL, *rpath = NULL; parse_push_pull_args(&argv[1], argc - 1, &lpath, &rpath, &show_progress, ©_attrs); parse_push_pull_args(&argv[1], argc - 1, &lpath, &rpath, ©_attrs); if (!lpath || !rpath || copy_attrs != 0) return usage(); return do_sync_push(lpath, rpath, show_progress) ? 0 : 1; return do_sync_push(lpath, rpath) ? 0 : 1; } else if (!strcmp(argv[0], "pull")) { bool show_progress = false; int copy_attrs = 0; const char* rpath = NULL, *lpath = "."; parse_push_pull_args(&argv[1], argc - 1, &rpath, &lpath, &show_progress, ©_attrs); parse_push_pull_args(&argv[1], argc - 1, &rpath, &lpath, ©_attrs); if (!rpath) return usage(); return do_sync_pull(rpath, lpath, show_progress, copy_attrs) ? 0 : 1; return do_sync_pull(rpath, lpath, copy_attrs) ? 0 : 1; } else if (!strcmp(argv[0], "install")) { if (argc < 2) return usage(); Loading Loading @@ -1768,7 +1763,7 @@ static int install_app(TransportType transport, const char* serial, int argc, co int result = -1; const char* apk_file = argv[last_apk]; std::string apk_dest = android::base::StringPrintf(where, adb_basename(apk_file).c_str()); if (!do_sync_push(apk_file, apk_dest.c_str(), false)) goto cleanup_apk; if (!do_sync_push(apk_file, apk_dest.c_str())) goto cleanup_apk; argv[last_apk] = apk_dest.c_str(); /* destination name, not source location */ result = pm_command(transport, serial, argc, argv); Loading adb/file_sync_client.cpp +140 −123 Original line number Diff line number Diff line Loading @@ -38,6 +38,7 @@ #include "adb_io.h" #include "adb_utils.h" #include "file_sync_service.h" #include "line_printer.h" #include <base/file.h> #include <base/strings.h> Loading @@ -49,36 +50,15 @@ struct syncsendbuf { char data[SYNC_DATA_MAX]; }; static long long NOW() { struct timeval tv; gettimeofday(&tv, 0); return ((long long) tv.tv_usec) + 1000000LL * ((long long) tv.tv_sec); } static void print_transfer_progress(uint64_t bytes_current, uint64_t bytes_total) { if (bytes_total == 0) return; fprintf(stderr, "\rTransferring: %" PRIu64 "/%" PRIu64 " (%d%%)", bytes_current, bytes_total, (int) (bytes_current * 100 / bytes_total)); if (bytes_current == bytes_total) { fputc('\n', stderr); } fflush(stderr); } class SyncConnection { public: SyncConnection() : total_bytes(0), start_time_(NOW()) { SyncConnection() : total_bytes(0), start_time_ms_(CurrentTimeMs()) { max = SYNC_DATA_MAX; // TODO: decide at runtime. std::string error; fd = adb_connect("sync:", &error); if (fd < 0) { fprintf(stderr, "adb: error: %s\n", error.c_str()); Error("connect failed: %s", error.c_str()); } } Loading @@ -86,7 +66,6 @@ class SyncConnection { if (!IsValid()) return; SendQuit(); ShowTransferRate(); adb_close(fd); } Loading @@ -95,7 +74,7 @@ class SyncConnection { bool SendRequest(int id, const char* path_and_mode) { size_t path_length = strlen(path_and_mode); if (path_length > 1024) { fprintf(stderr, "adb: SendRequest failed: path too long: %zu\n", path_length); Error("SendRequest failed: path too long: %zu", path_length); errno = ENAMETOOLONG; return false; } Loading @@ -115,11 +94,14 @@ 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* data, size_t data_length, unsigned mtime) { Print(rpath); size_t path_length = strlen(path_and_mode); if (path_length > 1024) { fprintf(stderr, "adb: SendSmallFile failed: path too long: %zu\n", path_length); Error("SendSmallFile failed: path too long: %zu", path_length); errno = ENAMETOOLONG; return false; } Loading Loading @@ -157,16 +139,14 @@ class SyncConnection { bool CopyDone(const char* from, const char* to) { syncmsg msg; if (!ReadFdExactly(fd, &msg.status, sizeof(msg.status))) { fprintf(stderr, "adb: failed to copy '%s' to '%s': no ID_DONE: %s\n", from, to, strerror(errno)); Error("failed to copy '%s' to '%s': no ID_DONE: %s", from, to, strerror(errno)); return false; } if (msg.status.id == ID_OKAY) { return true; } if (msg.status.id != ID_FAIL) { fprintf(stderr, "adb: failed to copy '%s' to '%s': unknown reason %d\n", from, to, msg.status.id); Error("failed to copy '%s' to '%s': unknown reason %d", from, to, msg.status.id); return false; } return ReportCopyFailure(from, to, msg); Loading @@ -175,15 +155,41 @@ class SyncConnection { bool ReportCopyFailure(const char* from, const char* to, const syncmsg& msg) { std::vector<char> buf(msg.status.msglen + 1); if (!ReadFdExactly(fd, &buf[0], msg.status.msglen)) { fprintf(stderr, "adb: failed to copy '%s' to '%s'; failed to read reason (!): %s\n", Error("failed to copy '%s' to '%s'; failed to read reason (!): %s", from, to, strerror(errno)); return false; } buf[msg.status.msglen] = 0; fprintf(stderr, "adb: failed to copy '%s' to '%s': %s\n", from, to, &buf[0]); Error("failed to copy '%s' to '%s': %s", from, to, &buf[0]); return false; } std::string TransferRate() { uint64_t ms = CurrentTimeMs() - start_time_ms_; if (total_bytes == 0 || ms == 0) return ""; double s = static_cast<double>(ms) / 1000LL; double rate = (static_cast<double>(total_bytes) / s) / (1024*1024); return android::base::StringPrintf(" %.1f MB/s (%" PRId64 " bytes in %.3fs)", rate, total_bytes, s); } void Print(const std::string& s) { // TODO: we actually don't want ELIDE; we want "ELIDE if smart, FULL if dumb". line_printer_.Print(s, LinePrinter::ELIDE); } void Error(const char* fmt, ...) __attribute__((__format__(ADB_FORMAT_ARCHETYPE, 2, 3))) { std::string s = "adb: error: "; va_list ap; va_start(ap, fmt); android::base::StringAppendV(&s, fmt, ap); va_end(ap); line_printer_.Print(s, LinePrinter::FULL); } uint64_t total_bytes; // TODO: add a char[max] buffer here, to replace syncsendbuf... Loading @@ -191,19 +197,18 @@ class SyncConnection { size_t max; private: uint64_t start_time_; uint64_t start_time_ms_; LinePrinter line_printer_; void SendQuit() { SendRequest(ID_QUIT, ""); // TODO: add a SendResponse? } void ShowTransferRate() { uint64_t t = NOW() - start_time_; if (total_bytes == 0 || t == 0) return; fprintf(stderr, "%lld KB/s (%" PRId64 " bytes in %lld.%03llds)\n", ((total_bytes * 1000000LL) / t) / 1024LL, total_bytes, (t / 1000000LL), (t % 1000000LL) / 1000LL); static uint64_t CurrentTimeMs() { struct timeval tv; gettimeofday(&tv, 0); // (Not clock_gettime because of Mac/Windows.) return static_cast<uint64_t>(tv.tv_sec) * 1000 + tv.tv_usec / 1000; } }; Loading Loading @@ -249,29 +254,26 @@ static bool sync_stat(SyncConnection& sc, const char* path, return sc.SendRequest(ID_STAT, path) && sync_finish_stat(sc, timestamp, mode, size); } static bool SendLargeFile(SyncConnection& sc, const char* path_and_mode, const char* path, unsigned mtime, bool show_progress) { static bool SendLargeFile(SyncConnection& sc, const char* path_and_mode, const char* lpath, const char* rpath, unsigned mtime) { if (!sc.SendRequest(ID_SEND, path_and_mode)) { fprintf(stderr, "adb: failed to send ID_SEND message '%s': %s\n", path_and_mode, strerror(errno)); sc.Error("failed to send ID_SEND message '%s': %s", path_and_mode, strerror(errno)); return false; } unsigned long long size = 0; if (show_progress) { // Determine local file size. struct stat st; if (stat(path, &st) == -1) { fprintf(stderr, "adb: cannot stat '%s': %s\n", path, strerror(errno)); if (stat(lpath, &st) == -1) { sc.Error("cannot stat '%s': %s", lpath, strerror(errno)); return false; } size = st.st_size; } uint64_t total_size = st.st_size; uint64_t bytes_copied = 0; int lfd = adb_open(path, O_RDONLY); int lfd = adb_open(lpath, O_RDONLY); if (lfd < 0) { fprintf(stderr, "adb: cannot open '%s': %s\n", path, strerror(errno)); sc.Error("cannot open '%s': %s", lpath, strerror(errno)); return false; } Loading @@ -281,7 +283,7 @@ static bool SendLargeFile(SyncConnection& sc, const char* path_and_mode, const c int ret = adb_read(lfd, sbuf.data, sc.max); if (ret <= 0) { if (ret < 0) { fprintf(stderr, "adb: cannot read '%s': %s\n", path, strerror(errno)); sc.Error("cannot read '%s': %s", lpath, strerror(errno)); adb_close(lfd); return false; } Loading @@ -295,9 +297,10 @@ static bool SendLargeFile(SyncConnection& sc, const char* path_and_mode, const c } sc.total_bytes += ret; if (show_progress) { print_transfer_progress(sc.total_bytes, size); } bytes_copied += ret; int percentage = static_cast<int>(bytes_copied * 100 / total_size); sc.Print(android::base::StringPrintf("%s: %d%%", rpath, percentage)); } adb_close(lfd); Loading @@ -306,8 +309,7 @@ static bool SendLargeFile(SyncConnection& sc, const char* path_and_mode, const c msg.data.id = ID_DONE; msg.data.size = mtime; if (!WriteFdExactly(sc.fd, &msg.data, sizeof(msg.data))) { fprintf(stderr, "adb: failed to send ID_DONE message for '%s': %s\n", path, strerror(errno)); sc.Error("failed to send ID_DONE message for '%s': %s", rpath, strerror(errno)); return false; } Loading @@ -315,7 +317,7 @@ static bool SendLargeFile(SyncConnection& sc, const char* path_and_mode, const c } static bool sync_send(SyncConnection& sc, const char* lpath, const char* rpath, unsigned mtime, mode_t mode, bool show_progress) unsigned mtime, mode_t mode) { std::string path_and_mode = android::base::StringPrintf("%s,%d", rpath, mode); Loading @@ -324,44 +326,48 @@ static bool sync_send(SyncConnection& sc, const char* lpath, const char* rpath, char buf[PATH_MAX]; ssize_t data_length = readlink(lpath, buf, PATH_MAX - 1); if (data_length == -1) { fprintf(stderr, "adb: readlink '%s' failed: %s\n", lpath, strerror(errno)); sc.Error("readlink '%s' failed: %s", lpath, strerror(errno)); return false; } buf[data_length++] = '\0'; if (!sc.SendSmallFile(path_and_mode.c_str(), buf, data_length, mtime)) return false; if (!sc.SendSmallFile(path_and_mode.c_str(), rpath, buf, data_length, mtime)) return false; return sc.CopyDone(lpath, rpath); #endif } if (!S_ISREG(mode)) { fprintf(stderr, "adb: local file '%s' has unsupported mode: 0o%o\n", lpath, mode); sc.Error("local file '%s' has unsupported mode: 0o%o", lpath, mode); return false; } struct stat st; if (stat(lpath, &st) == -1) { fprintf(stderr, "adb: failed to stat local file '%s': %s\n", lpath, strerror(errno)); sc.Error("failed to stat local file '%s': %s", lpath, strerror(errno)); return false; } if (st.st_size < SYNC_DATA_MAX) { std::string data; if (!android::base::ReadFileToString(lpath, &data)) { fprintf(stderr, "adb: failed to read all of '%s': %s\n", lpath, strerror(errno)); sc.Error("failed to read all of '%s': %s", lpath, strerror(errno)); return false; } if (!sc.SendSmallFile(path_and_mode.c_str(), rpath, data.data(), data.size(), mtime)) { return false; } if (!sc.SendSmallFile(path_and_mode.c_str(), data.data(), data.size(), mtime)) return false; } else { if (!SendLargeFile(sc, path_and_mode.c_str(), lpath, mtime, show_progress)) return false; if (!SendLargeFile(sc, path_and_mode.c_str(), lpath, rpath, mtime)) { return false; } } return sc.CopyDone(lpath, rpath); } static bool sync_recv(SyncConnection& sc, const char* rpath, const char* lpath, bool show_progress) { static bool sync_recv(SyncConnection& sc, const char* rpath, const char* lpath) { sc.Print(rpath); unsigned size = 0; if (show_progress) { if (!sync_stat(sc, rpath, nullptr, nullptr, &size)) return false; } if (!sc.SendRequest(ID_RECV, rpath)) return false; Loading @@ -369,10 +375,11 @@ static bool sync_recv(SyncConnection& sc, const char* rpath, const char* lpath, mkdirs(lpath); int lfd = adb_creat(lpath, 0644); if (lfd < 0) { fprintf(stderr, "adb: cannot create '%s': %s\n", lpath, strerror(errno)); sc.Error("cannot create '%s': %s", lpath, strerror(errno)); return false; } uint64_t bytes_copied = 0; while (true) { syncmsg msg; if (!ReadFdExactly(sc.fd, &msg.data, sizeof(msg.data))) { Loading @@ -391,7 +398,7 @@ static bool sync_recv(SyncConnection& sc, const char* rpath, const char* lpath, } if (msg.data.size > sc.max) { fprintf(stderr, "adb: msg.data.size too large: %u (max %zu)\n", msg.data.size, sc.max); sc.Error("msg.data.size too large: %u (max %zu)", msg.data.size, sc.max); adb_close(lfd); adb_unlink(lpath); return false; Loading @@ -405,7 +412,7 @@ static bool sync_recv(SyncConnection& sc, const char* rpath, const char* lpath, } if (!WriteFdExactly(lfd, buffer, msg.data.size)) { fprintf(stderr, "adb: cannot write '%s': %s\n", lpath, strerror(errno)); sc.Error("cannot write '%s': %s", lpath, strerror(errno)); adb_close(lfd); adb_unlink(lpath); return false; Loading @@ -413,9 +420,10 @@ static bool sync_recv(SyncConnection& sc, const char* rpath, const char* lpath, sc.total_bytes += msg.data.size; if (show_progress) { print_transfer_progress(sc.total_bytes, size); } bytes_copied += msg.data.size; int percentage = static_cast<int>(bytes_copied * 100 / size); sc.Print(android::base::StringPrintf("%s: %d%%", rpath, percentage)); } adb_close(lfd); Loading Loading @@ -475,13 +483,14 @@ static bool IsDotOrDotDot(const char* name) { return name[0] == '.' && (name[1] == '\0' || (name[1] == '.' && name[2] == '\0')); } static int local_build_list(copyinfo** filelist, const char* lpath, const char* rpath) { static int local_build_list(SyncConnection& sc, copyinfo** filelist, const char* lpath, const char* rpath) { copyinfo *dirlist = 0; copyinfo *ci, *next; std::unique_ptr<DIR, int(*)(DIR*)> dir(opendir(lpath), closedir); if (!dir) { fprintf(stderr, "adb: cannot open '%s': %s\n", lpath, strerror(errno)); sc.Error("cannot open '%s': %s", lpath, strerror(errno)); return -1; } Loading @@ -491,7 +500,7 @@ static int local_build_list(copyinfo** filelist, const char* lpath, const char* char stat_path[PATH_MAX]; if (strlen(lpath) + strlen(de->d_name) + 1 > sizeof(stat_path)) { fprintf(stderr, "adb: skipping long path '%s%s'\n", lpath, de->d_name); sc.Error("skipping long path '%s%s'", lpath, de->d_name); continue; } strcpy(stat_path, lpath); Loading @@ -506,7 +515,7 @@ static int local_build_list(copyinfo** filelist, const char* lpath, const char* } else { ci = mkcopyinfo(lpath, rpath, de->d_name, 0); if (!S_ISREG(st.st_mode) && !S_ISLNK(st.st_mode)) { fprintf(stderr, "adb: skipping special file '%s'\n", ci->src); sc.Error("skipping special file '%s'", ci->src); free(ci); } else { ci->time = st.st_mtime; Loading @@ -517,7 +526,7 @@ static int local_build_list(copyinfo** filelist, const char* lpath, const char* } } } else { fprintf(stderr, "adb: cannot lstat '%s': %s\n",stat_path , strerror(errno)); sc.Error("cannot lstat '%s': %s",stat_path , strerror(errno)); } } Loading @@ -525,7 +534,7 @@ static int local_build_list(copyinfo** filelist, const char* lpath, const char* dir.reset(); for (ci = dirlist; ci != 0; ci = next) { next = ci->next; local_build_list(filelist, ci->src, ci->dst); local_build_list(sc, filelist, ci->src, ci->dst); free(ci); } Loading Loading @@ -555,7 +564,7 @@ static bool copy_local_dir_remote(SyncConnection& sc, const char* lpath, const c rpath = tmp; } if (local_build_list(&filelist, lpath, rpath)) { if (local_build_list(sc, &filelist, lpath, rpath)) { return false; } Loading @@ -578,10 +587,13 @@ static bool copy_local_dir_remote(SyncConnection& sc, const char* lpath, const c for (ci = filelist; ci != 0; ci = next) { next = ci->next; if (ci->flag == 0) { fprintf(stderr, "%spush: %s -> %s\n", list_only ? "would " : "", ci->src, ci->dst); if (!list_only && !sync_send(sc, ci->src, ci->dst, ci->time, ci->mode, false)) { if (list_only) { fprintf(stderr, "would push: %s -> %s\n", ci->src, ci->dst); } else { if (!sync_send(sc, ci->src, ci->dst, ci->time, ci->mode)) { return false; } } pushed++; } else { skipped++; Loading @@ -589,20 +601,21 @@ static bool copy_local_dir_remote(SyncConnection& sc, const char* lpath, const c free(ci); } fprintf(stderr, "%d file%s pushed. %d file%s skipped.\n", sc.Print(android::base::StringPrintf("%s: %d file%s pushed. %d file%s skipped.%s\n", rpath, pushed, (pushed == 1) ? "" : "s", skipped, (skipped == 1) ? "" : "s"); skipped, (skipped == 1) ? "" : "s", sc.TransferRate().c_str())); return true; } bool do_sync_push(const char* lpath, const char* rpath, bool show_progress) { bool do_sync_push(const char* lpath, const char* rpath) { SyncConnection sc; if (!sc.IsValid()) return false; struct stat st; if (stat(lpath, &st)) { fprintf(stderr, "adb: cannot stat '%s': %s\n", lpath, strerror(errno)); sc.Error("cannot stat '%s': %s", lpath, strerror(errno)); return false; } Loading @@ -619,11 +632,13 @@ bool do_sync_push(const char* lpath, const char* rpath, bool show_progress) { path_holder = android::base::StringPrintf("%s/%s", rpath, adb_basename(lpath).c_str()); rpath = path_holder.c_str(); } return sync_send(sc, lpath, rpath, st.st_mtime, st.st_mode, show_progress); bool result = sync_send(sc, lpath, rpath, st.st_mtime, st.st_mode); sc.Print("\n"); return result; } struct sync_ls_build_list_cb_args { SyncConnection* sc; copyinfo** filelist; copyinfo** dirlist; const char* rpath; Loading @@ -633,7 +648,7 @@ struct sync_ls_build_list_cb_args { static void sync_ls_build_list_cb(unsigned mode, unsigned size, unsigned time, const char* name, void* cookie) { sync_ls_build_list_cb_args *args = (sync_ls_build_list_cb_args *)cookie; sync_ls_build_list_cb_args* args = static_cast<sync_ls_build_list_cb_args*>(cookie); copyinfo *ci; if (S_ISDIR(mode)) { Loading @@ -655,22 +670,23 @@ static void sync_ls_build_list_cb(unsigned mode, unsigned size, unsigned time, ci->next = *filelist; *filelist = ci; } else { fprintf(stderr, "adb: skipping special file '%s'\n", name); args->sc->Print(android::base::StringPrintf("skipping special file '%s'\n", name)); } } static bool remote_build_list(SyncConnection& sc, copyinfo **filelist, const char *rpath, const char *lpath) { copyinfo *dirlist = NULL; sync_ls_build_list_cb_args args; copyinfo* dirlist = nullptr; sync_ls_build_list_cb_args args; args.sc = ≻ args.filelist = filelist; args.dirlist = &dirlist; args.rpath = rpath; args.lpath = lpath; // Put the files/dirs in rpath on the lists. if (!sync_ls(sc, rpath, sync_ls_build_list_cb, (void *)&args)) { if (!sync_ls(sc, rpath, sync_ls_build_list_cb, &args)) { return false; } Loading Loading @@ -710,7 +726,7 @@ static bool copy_remote_dir_local(SyncConnection& sc, const char* rpath, const c if (lpath_clean.back() != '/') lpath_clean.push_back('/'); // Recursively build the list of files to copy. fprintf(stderr, "pull: building file list...\n"); sc.Print("pull: building file list..."); copyinfo* filelist = nullptr; if (!remote_build_list(sc, &filelist, rpath_clean.c_str(), lpath_clean.c_str())) return false; Loading @@ -720,8 +736,8 @@ static bool copy_remote_dir_local(SyncConnection& sc, const char* rpath, const c while (ci) { copyinfo* next = ci->next; if (ci->flag == 0) { fprintf(stderr, "pull: %s -> %s\n", ci->src, ci->dst); if (!sync_recv(sc, ci->src, ci->dst, false)) { sc.Print(android::base::StringPrintf("pull: %s -> %s", ci->src, ci->dst)); if (!sync_recv(sc, ci->src, ci->dst)) { return false; } Loading @@ -736,20 +752,22 @@ static bool copy_remote_dir_local(SyncConnection& sc, const char* rpath, const c ci = next; } fprintf(stderr, "%d file%s pulled. %d file%s skipped.\n", sc.Print(android::base::StringPrintf("%s: %d file%s pulled. %d file%s skipped.%s\n", rpath, pulled, (pulled == 1) ? "" : "s", skipped, (skipped == 1) ? "" : "s"); skipped, (skipped == 1) ? "" : "s", sc.TransferRate().c_str())); return true; } bool do_sync_pull(const char* rpath, const char* lpath, bool show_progress, int copy_attrs) { bool do_sync_pull(const char* rpath, const char* lpath, int copy_attrs) { SyncConnection sc; if (!sc.IsValid()) return false; unsigned mode, time; if (!sync_stat(sc, rpath, &time, &mode, nullptr)) return false; if (mode == 0) { fprintf(stderr, "adb: remote object '%s' does not exist\n", rpath); sc.Error("remote object '%s' does not exist", rpath); return false; } Loading @@ -764,25 +782,24 @@ bool do_sync_pull(const char* rpath, const char* lpath, bool show_progress, int lpath = path_holder.c_str(); } } if (!sync_recv(sc, rpath, lpath, show_progress)) { if (!sync_recv(sc, rpath, lpath)) { return false; } else { if (copy_attrs && set_time_and_mode(lpath, time, mode)) { return false; } } sc.Print("\n"); return true; } else if (S_ISDIR(mode)) { return copy_remote_dir_local(sc, rpath, lpath, copy_attrs); } fprintf(stderr, "adb: remote object '%s' not a file or directory\n", rpath); sc.Error("remote object '%s' not a file or directory", rpath); return false; } bool do_sync_sync(const std::string& lpath, const std::string& rpath, bool list_only) { fprintf(stderr, "syncing %s...\n", rpath.c_str()); SyncConnection sc; if (!sc.IsValid()) return false; Loading adb/file_sync_service.h +2 −2 Original line number Diff line number Diff line Loading @@ -64,9 +64,9 @@ union syncmsg { void file_sync_service(int fd, void* cookie); bool do_sync_ls(const char* path); bool do_sync_push(const char* lpath, const char* rpath, bool show_progress); bool do_sync_push(const char* lpath, const char* rpath); bool do_sync_sync(const std::string& lpath, const std::string& rpath, bool list_only); bool do_sync_pull(const char* rpath, const char* lpath, bool show_progress, int copy_attrs); bool do_sync_pull(const char* rpath, const char* lpath, int copy_attrs); #define SYNC_DATA_MAX (64*1024) Loading Loading
adb/Android.mk +3 −2 Original line number Diff line number Diff line Loading @@ -213,12 +213,13 @@ LOCAL_STATIC_LIBRARIES_windows := AdbWinApi LOCAL_REQUIRED_MODULES_windows := AdbWinApi AdbWinUsbApi LOCAL_SRC_FILES := \ adb_client.cpp \ client/main.cpp \ console.cpp \ commandline.cpp \ adb_client.cpp \ services.cpp \ file_sync_client.cpp \ line_printer.cpp \ services.cpp \ shell_service_protocol.cpp \ LOCAL_CFLAGS += \ Loading
adb/commandline.cpp +10 −15 Original line number Diff line number Diff line Loading @@ -101,12 +101,10 @@ static void help() { " will disconnect from all connected TCP/IP devices.\n" "\n" "device commands:\n" " adb push [-p] <local> <remote>\n" " adb push <local> <remote>\n" " - copy file/dir to device\n" " ('-p' to display the transfer progress)\n" " adb pull [-p] [-a] <remote> [<local>]\n" " adb pull [-a] <remote> [<local>]\n" " - copy file/dir from device\n" " ('-p' to display the transfer progress)\n" " ('-a' means copy timestamp and mode)\n" " adb sync [ <directory> ] - copy host->device only if changed\n" " (-l means list but don't copy)\n" Loading Loading @@ -1065,15 +1063,14 @@ static std::string find_product_out_path(const std::string& hint) { return path; } static void parse_push_pull_args(const char **arg, int narg, char const **path1, char const **path2, bool* show_progress, static void parse_push_pull_args(const char **arg, int narg, char const **path1, char const **path2, int *copy_attrs) { *show_progress = false; *copy_attrs = 0; while (narg > 0) { if (!strcmp(*arg, "-p")) { *show_progress = true; // Silently ignore for backwards compatibility. } else if (!strcmp(*arg, "-a")) { *copy_attrs = 1; } else { Loading Loading @@ -1561,22 +1558,20 @@ int adb_commandline(int argc, const char **argv) { return do_sync_ls(argv[1]) ? 0 : 1; } else if (!strcmp(argv[0], "push")) { bool show_progress = false; int copy_attrs = 0; const char* lpath = NULL, *rpath = NULL; parse_push_pull_args(&argv[1], argc - 1, &lpath, &rpath, &show_progress, ©_attrs); parse_push_pull_args(&argv[1], argc - 1, &lpath, &rpath, ©_attrs); if (!lpath || !rpath || copy_attrs != 0) return usage(); return do_sync_push(lpath, rpath, show_progress) ? 0 : 1; return do_sync_push(lpath, rpath) ? 0 : 1; } else if (!strcmp(argv[0], "pull")) { bool show_progress = false; int copy_attrs = 0; const char* rpath = NULL, *lpath = "."; parse_push_pull_args(&argv[1], argc - 1, &rpath, &lpath, &show_progress, ©_attrs); parse_push_pull_args(&argv[1], argc - 1, &rpath, &lpath, ©_attrs); if (!rpath) return usage(); return do_sync_pull(rpath, lpath, show_progress, copy_attrs) ? 0 : 1; return do_sync_pull(rpath, lpath, copy_attrs) ? 0 : 1; } else if (!strcmp(argv[0], "install")) { if (argc < 2) return usage(); Loading Loading @@ -1768,7 +1763,7 @@ static int install_app(TransportType transport, const char* serial, int argc, co int result = -1; const char* apk_file = argv[last_apk]; std::string apk_dest = android::base::StringPrintf(where, adb_basename(apk_file).c_str()); if (!do_sync_push(apk_file, apk_dest.c_str(), false)) goto cleanup_apk; if (!do_sync_push(apk_file, apk_dest.c_str())) goto cleanup_apk; argv[last_apk] = apk_dest.c_str(); /* destination name, not source location */ result = pm_command(transport, serial, argc, argv); Loading
adb/file_sync_client.cpp +140 −123 Original line number Diff line number Diff line Loading @@ -38,6 +38,7 @@ #include "adb_io.h" #include "adb_utils.h" #include "file_sync_service.h" #include "line_printer.h" #include <base/file.h> #include <base/strings.h> Loading @@ -49,36 +50,15 @@ struct syncsendbuf { char data[SYNC_DATA_MAX]; }; static long long NOW() { struct timeval tv; gettimeofday(&tv, 0); return ((long long) tv.tv_usec) + 1000000LL * ((long long) tv.tv_sec); } static void print_transfer_progress(uint64_t bytes_current, uint64_t bytes_total) { if (bytes_total == 0) return; fprintf(stderr, "\rTransferring: %" PRIu64 "/%" PRIu64 " (%d%%)", bytes_current, bytes_total, (int) (bytes_current * 100 / bytes_total)); if (bytes_current == bytes_total) { fputc('\n', stderr); } fflush(stderr); } class SyncConnection { public: SyncConnection() : total_bytes(0), start_time_(NOW()) { SyncConnection() : total_bytes(0), start_time_ms_(CurrentTimeMs()) { max = SYNC_DATA_MAX; // TODO: decide at runtime. std::string error; fd = adb_connect("sync:", &error); if (fd < 0) { fprintf(stderr, "adb: error: %s\n", error.c_str()); Error("connect failed: %s", error.c_str()); } } Loading @@ -86,7 +66,6 @@ class SyncConnection { if (!IsValid()) return; SendQuit(); ShowTransferRate(); adb_close(fd); } Loading @@ -95,7 +74,7 @@ class SyncConnection { bool SendRequest(int id, const char* path_and_mode) { size_t path_length = strlen(path_and_mode); if (path_length > 1024) { fprintf(stderr, "adb: SendRequest failed: path too long: %zu\n", path_length); Error("SendRequest failed: path too long: %zu", path_length); errno = ENAMETOOLONG; return false; } Loading @@ -115,11 +94,14 @@ 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* data, size_t data_length, unsigned mtime) { Print(rpath); size_t path_length = strlen(path_and_mode); if (path_length > 1024) { fprintf(stderr, "adb: SendSmallFile failed: path too long: %zu\n", path_length); Error("SendSmallFile failed: path too long: %zu", path_length); errno = ENAMETOOLONG; return false; } Loading Loading @@ -157,16 +139,14 @@ class SyncConnection { bool CopyDone(const char* from, const char* to) { syncmsg msg; if (!ReadFdExactly(fd, &msg.status, sizeof(msg.status))) { fprintf(stderr, "adb: failed to copy '%s' to '%s': no ID_DONE: %s\n", from, to, strerror(errno)); Error("failed to copy '%s' to '%s': no ID_DONE: %s", from, to, strerror(errno)); return false; } if (msg.status.id == ID_OKAY) { return true; } if (msg.status.id != ID_FAIL) { fprintf(stderr, "adb: failed to copy '%s' to '%s': unknown reason %d\n", from, to, msg.status.id); Error("failed to copy '%s' to '%s': unknown reason %d", from, to, msg.status.id); return false; } return ReportCopyFailure(from, to, msg); Loading @@ -175,15 +155,41 @@ class SyncConnection { bool ReportCopyFailure(const char* from, const char* to, const syncmsg& msg) { std::vector<char> buf(msg.status.msglen + 1); if (!ReadFdExactly(fd, &buf[0], msg.status.msglen)) { fprintf(stderr, "adb: failed to copy '%s' to '%s'; failed to read reason (!): %s\n", Error("failed to copy '%s' to '%s'; failed to read reason (!): %s", from, to, strerror(errno)); return false; } buf[msg.status.msglen] = 0; fprintf(stderr, "adb: failed to copy '%s' to '%s': %s\n", from, to, &buf[0]); Error("failed to copy '%s' to '%s': %s", from, to, &buf[0]); return false; } std::string TransferRate() { uint64_t ms = CurrentTimeMs() - start_time_ms_; if (total_bytes == 0 || ms == 0) return ""; double s = static_cast<double>(ms) / 1000LL; double rate = (static_cast<double>(total_bytes) / s) / (1024*1024); return android::base::StringPrintf(" %.1f MB/s (%" PRId64 " bytes in %.3fs)", rate, total_bytes, s); } void Print(const std::string& s) { // TODO: we actually don't want ELIDE; we want "ELIDE if smart, FULL if dumb". line_printer_.Print(s, LinePrinter::ELIDE); } void Error(const char* fmt, ...) __attribute__((__format__(ADB_FORMAT_ARCHETYPE, 2, 3))) { std::string s = "adb: error: "; va_list ap; va_start(ap, fmt); android::base::StringAppendV(&s, fmt, ap); va_end(ap); line_printer_.Print(s, LinePrinter::FULL); } uint64_t total_bytes; // TODO: add a char[max] buffer here, to replace syncsendbuf... Loading @@ -191,19 +197,18 @@ class SyncConnection { size_t max; private: uint64_t start_time_; uint64_t start_time_ms_; LinePrinter line_printer_; void SendQuit() { SendRequest(ID_QUIT, ""); // TODO: add a SendResponse? } void ShowTransferRate() { uint64_t t = NOW() - start_time_; if (total_bytes == 0 || t == 0) return; fprintf(stderr, "%lld KB/s (%" PRId64 " bytes in %lld.%03llds)\n", ((total_bytes * 1000000LL) / t) / 1024LL, total_bytes, (t / 1000000LL), (t % 1000000LL) / 1000LL); static uint64_t CurrentTimeMs() { struct timeval tv; gettimeofday(&tv, 0); // (Not clock_gettime because of Mac/Windows.) return static_cast<uint64_t>(tv.tv_sec) * 1000 + tv.tv_usec / 1000; } }; Loading Loading @@ -249,29 +254,26 @@ static bool sync_stat(SyncConnection& sc, const char* path, return sc.SendRequest(ID_STAT, path) && sync_finish_stat(sc, timestamp, mode, size); } static bool SendLargeFile(SyncConnection& sc, const char* path_and_mode, const char* path, unsigned mtime, bool show_progress) { static bool SendLargeFile(SyncConnection& sc, const char* path_and_mode, const char* lpath, const char* rpath, unsigned mtime) { if (!sc.SendRequest(ID_SEND, path_and_mode)) { fprintf(stderr, "adb: failed to send ID_SEND message '%s': %s\n", path_and_mode, strerror(errno)); sc.Error("failed to send ID_SEND message '%s': %s", path_and_mode, strerror(errno)); return false; } unsigned long long size = 0; if (show_progress) { // Determine local file size. struct stat st; if (stat(path, &st) == -1) { fprintf(stderr, "adb: cannot stat '%s': %s\n", path, strerror(errno)); if (stat(lpath, &st) == -1) { sc.Error("cannot stat '%s': %s", lpath, strerror(errno)); return false; } size = st.st_size; } uint64_t total_size = st.st_size; uint64_t bytes_copied = 0; int lfd = adb_open(path, O_RDONLY); int lfd = adb_open(lpath, O_RDONLY); if (lfd < 0) { fprintf(stderr, "adb: cannot open '%s': %s\n", path, strerror(errno)); sc.Error("cannot open '%s': %s", lpath, strerror(errno)); return false; } Loading @@ -281,7 +283,7 @@ static bool SendLargeFile(SyncConnection& sc, const char* path_and_mode, const c int ret = adb_read(lfd, sbuf.data, sc.max); if (ret <= 0) { if (ret < 0) { fprintf(stderr, "adb: cannot read '%s': %s\n", path, strerror(errno)); sc.Error("cannot read '%s': %s", lpath, strerror(errno)); adb_close(lfd); return false; } Loading @@ -295,9 +297,10 @@ static bool SendLargeFile(SyncConnection& sc, const char* path_and_mode, const c } sc.total_bytes += ret; if (show_progress) { print_transfer_progress(sc.total_bytes, size); } bytes_copied += ret; int percentage = static_cast<int>(bytes_copied * 100 / total_size); sc.Print(android::base::StringPrintf("%s: %d%%", rpath, percentage)); } adb_close(lfd); Loading @@ -306,8 +309,7 @@ static bool SendLargeFile(SyncConnection& sc, const char* path_and_mode, const c msg.data.id = ID_DONE; msg.data.size = mtime; if (!WriteFdExactly(sc.fd, &msg.data, sizeof(msg.data))) { fprintf(stderr, "adb: failed to send ID_DONE message for '%s': %s\n", path, strerror(errno)); sc.Error("failed to send ID_DONE message for '%s': %s", rpath, strerror(errno)); return false; } Loading @@ -315,7 +317,7 @@ static bool SendLargeFile(SyncConnection& sc, const char* path_and_mode, const c } static bool sync_send(SyncConnection& sc, const char* lpath, const char* rpath, unsigned mtime, mode_t mode, bool show_progress) unsigned mtime, mode_t mode) { std::string path_and_mode = android::base::StringPrintf("%s,%d", rpath, mode); Loading @@ -324,44 +326,48 @@ static bool sync_send(SyncConnection& sc, const char* lpath, const char* rpath, char buf[PATH_MAX]; ssize_t data_length = readlink(lpath, buf, PATH_MAX - 1); if (data_length == -1) { fprintf(stderr, "adb: readlink '%s' failed: %s\n", lpath, strerror(errno)); sc.Error("readlink '%s' failed: %s", lpath, strerror(errno)); return false; } buf[data_length++] = '\0'; if (!sc.SendSmallFile(path_and_mode.c_str(), buf, data_length, mtime)) return false; if (!sc.SendSmallFile(path_and_mode.c_str(), rpath, buf, data_length, mtime)) return false; return sc.CopyDone(lpath, rpath); #endif } if (!S_ISREG(mode)) { fprintf(stderr, "adb: local file '%s' has unsupported mode: 0o%o\n", lpath, mode); sc.Error("local file '%s' has unsupported mode: 0o%o", lpath, mode); return false; } struct stat st; if (stat(lpath, &st) == -1) { fprintf(stderr, "adb: failed to stat local file '%s': %s\n", lpath, strerror(errno)); sc.Error("failed to stat local file '%s': %s", lpath, strerror(errno)); return false; } if (st.st_size < SYNC_DATA_MAX) { std::string data; if (!android::base::ReadFileToString(lpath, &data)) { fprintf(stderr, "adb: failed to read all of '%s': %s\n", lpath, strerror(errno)); sc.Error("failed to read all of '%s': %s", lpath, strerror(errno)); return false; } if (!sc.SendSmallFile(path_and_mode.c_str(), rpath, data.data(), data.size(), mtime)) { return false; } if (!sc.SendSmallFile(path_and_mode.c_str(), data.data(), data.size(), mtime)) return false; } else { if (!SendLargeFile(sc, path_and_mode.c_str(), lpath, mtime, show_progress)) return false; if (!SendLargeFile(sc, path_and_mode.c_str(), lpath, rpath, mtime)) { return false; } } return sc.CopyDone(lpath, rpath); } static bool sync_recv(SyncConnection& sc, const char* rpath, const char* lpath, bool show_progress) { static bool sync_recv(SyncConnection& sc, const char* rpath, const char* lpath) { sc.Print(rpath); unsigned size = 0; if (show_progress) { if (!sync_stat(sc, rpath, nullptr, nullptr, &size)) return false; } if (!sc.SendRequest(ID_RECV, rpath)) return false; Loading @@ -369,10 +375,11 @@ static bool sync_recv(SyncConnection& sc, const char* rpath, const char* lpath, mkdirs(lpath); int lfd = adb_creat(lpath, 0644); if (lfd < 0) { fprintf(stderr, "adb: cannot create '%s': %s\n", lpath, strerror(errno)); sc.Error("cannot create '%s': %s", lpath, strerror(errno)); return false; } uint64_t bytes_copied = 0; while (true) { syncmsg msg; if (!ReadFdExactly(sc.fd, &msg.data, sizeof(msg.data))) { Loading @@ -391,7 +398,7 @@ static bool sync_recv(SyncConnection& sc, const char* rpath, const char* lpath, } if (msg.data.size > sc.max) { fprintf(stderr, "adb: msg.data.size too large: %u (max %zu)\n", msg.data.size, sc.max); sc.Error("msg.data.size too large: %u (max %zu)", msg.data.size, sc.max); adb_close(lfd); adb_unlink(lpath); return false; Loading @@ -405,7 +412,7 @@ static bool sync_recv(SyncConnection& sc, const char* rpath, const char* lpath, } if (!WriteFdExactly(lfd, buffer, msg.data.size)) { fprintf(stderr, "adb: cannot write '%s': %s\n", lpath, strerror(errno)); sc.Error("cannot write '%s': %s", lpath, strerror(errno)); adb_close(lfd); adb_unlink(lpath); return false; Loading @@ -413,9 +420,10 @@ static bool sync_recv(SyncConnection& sc, const char* rpath, const char* lpath, sc.total_bytes += msg.data.size; if (show_progress) { print_transfer_progress(sc.total_bytes, size); } bytes_copied += msg.data.size; int percentage = static_cast<int>(bytes_copied * 100 / size); sc.Print(android::base::StringPrintf("%s: %d%%", rpath, percentage)); } adb_close(lfd); Loading Loading @@ -475,13 +483,14 @@ static bool IsDotOrDotDot(const char* name) { return name[0] == '.' && (name[1] == '\0' || (name[1] == '.' && name[2] == '\0')); } static int local_build_list(copyinfo** filelist, const char* lpath, const char* rpath) { static int local_build_list(SyncConnection& sc, copyinfo** filelist, const char* lpath, const char* rpath) { copyinfo *dirlist = 0; copyinfo *ci, *next; std::unique_ptr<DIR, int(*)(DIR*)> dir(opendir(lpath), closedir); if (!dir) { fprintf(stderr, "adb: cannot open '%s': %s\n", lpath, strerror(errno)); sc.Error("cannot open '%s': %s", lpath, strerror(errno)); return -1; } Loading @@ -491,7 +500,7 @@ static int local_build_list(copyinfo** filelist, const char* lpath, const char* char stat_path[PATH_MAX]; if (strlen(lpath) + strlen(de->d_name) + 1 > sizeof(stat_path)) { fprintf(stderr, "adb: skipping long path '%s%s'\n", lpath, de->d_name); sc.Error("skipping long path '%s%s'", lpath, de->d_name); continue; } strcpy(stat_path, lpath); Loading @@ -506,7 +515,7 @@ static int local_build_list(copyinfo** filelist, const char* lpath, const char* } else { ci = mkcopyinfo(lpath, rpath, de->d_name, 0); if (!S_ISREG(st.st_mode) && !S_ISLNK(st.st_mode)) { fprintf(stderr, "adb: skipping special file '%s'\n", ci->src); sc.Error("skipping special file '%s'", ci->src); free(ci); } else { ci->time = st.st_mtime; Loading @@ -517,7 +526,7 @@ static int local_build_list(copyinfo** filelist, const char* lpath, const char* } } } else { fprintf(stderr, "adb: cannot lstat '%s': %s\n",stat_path , strerror(errno)); sc.Error("cannot lstat '%s': %s",stat_path , strerror(errno)); } } Loading @@ -525,7 +534,7 @@ static int local_build_list(copyinfo** filelist, const char* lpath, const char* dir.reset(); for (ci = dirlist; ci != 0; ci = next) { next = ci->next; local_build_list(filelist, ci->src, ci->dst); local_build_list(sc, filelist, ci->src, ci->dst); free(ci); } Loading Loading @@ -555,7 +564,7 @@ static bool copy_local_dir_remote(SyncConnection& sc, const char* lpath, const c rpath = tmp; } if (local_build_list(&filelist, lpath, rpath)) { if (local_build_list(sc, &filelist, lpath, rpath)) { return false; } Loading @@ -578,10 +587,13 @@ static bool copy_local_dir_remote(SyncConnection& sc, const char* lpath, const c for (ci = filelist; ci != 0; ci = next) { next = ci->next; if (ci->flag == 0) { fprintf(stderr, "%spush: %s -> %s\n", list_only ? "would " : "", ci->src, ci->dst); if (!list_only && !sync_send(sc, ci->src, ci->dst, ci->time, ci->mode, false)) { if (list_only) { fprintf(stderr, "would push: %s -> %s\n", ci->src, ci->dst); } else { if (!sync_send(sc, ci->src, ci->dst, ci->time, ci->mode)) { return false; } } pushed++; } else { skipped++; Loading @@ -589,20 +601,21 @@ static bool copy_local_dir_remote(SyncConnection& sc, const char* lpath, const c free(ci); } fprintf(stderr, "%d file%s pushed. %d file%s skipped.\n", sc.Print(android::base::StringPrintf("%s: %d file%s pushed. %d file%s skipped.%s\n", rpath, pushed, (pushed == 1) ? "" : "s", skipped, (skipped == 1) ? "" : "s"); skipped, (skipped == 1) ? "" : "s", sc.TransferRate().c_str())); return true; } bool do_sync_push(const char* lpath, const char* rpath, bool show_progress) { bool do_sync_push(const char* lpath, const char* rpath) { SyncConnection sc; if (!sc.IsValid()) return false; struct stat st; if (stat(lpath, &st)) { fprintf(stderr, "adb: cannot stat '%s': %s\n", lpath, strerror(errno)); sc.Error("cannot stat '%s': %s", lpath, strerror(errno)); return false; } Loading @@ -619,11 +632,13 @@ bool do_sync_push(const char* lpath, const char* rpath, bool show_progress) { path_holder = android::base::StringPrintf("%s/%s", rpath, adb_basename(lpath).c_str()); rpath = path_holder.c_str(); } return sync_send(sc, lpath, rpath, st.st_mtime, st.st_mode, show_progress); bool result = sync_send(sc, lpath, rpath, st.st_mtime, st.st_mode); sc.Print("\n"); return result; } struct sync_ls_build_list_cb_args { SyncConnection* sc; copyinfo** filelist; copyinfo** dirlist; const char* rpath; Loading @@ -633,7 +648,7 @@ struct sync_ls_build_list_cb_args { static void sync_ls_build_list_cb(unsigned mode, unsigned size, unsigned time, const char* name, void* cookie) { sync_ls_build_list_cb_args *args = (sync_ls_build_list_cb_args *)cookie; sync_ls_build_list_cb_args* args = static_cast<sync_ls_build_list_cb_args*>(cookie); copyinfo *ci; if (S_ISDIR(mode)) { Loading @@ -655,22 +670,23 @@ static void sync_ls_build_list_cb(unsigned mode, unsigned size, unsigned time, ci->next = *filelist; *filelist = ci; } else { fprintf(stderr, "adb: skipping special file '%s'\n", name); args->sc->Print(android::base::StringPrintf("skipping special file '%s'\n", name)); } } static bool remote_build_list(SyncConnection& sc, copyinfo **filelist, const char *rpath, const char *lpath) { copyinfo *dirlist = NULL; sync_ls_build_list_cb_args args; copyinfo* dirlist = nullptr; sync_ls_build_list_cb_args args; args.sc = ≻ args.filelist = filelist; args.dirlist = &dirlist; args.rpath = rpath; args.lpath = lpath; // Put the files/dirs in rpath on the lists. if (!sync_ls(sc, rpath, sync_ls_build_list_cb, (void *)&args)) { if (!sync_ls(sc, rpath, sync_ls_build_list_cb, &args)) { return false; } Loading Loading @@ -710,7 +726,7 @@ static bool copy_remote_dir_local(SyncConnection& sc, const char* rpath, const c if (lpath_clean.back() != '/') lpath_clean.push_back('/'); // Recursively build the list of files to copy. fprintf(stderr, "pull: building file list...\n"); sc.Print("pull: building file list..."); copyinfo* filelist = nullptr; if (!remote_build_list(sc, &filelist, rpath_clean.c_str(), lpath_clean.c_str())) return false; Loading @@ -720,8 +736,8 @@ static bool copy_remote_dir_local(SyncConnection& sc, const char* rpath, const c while (ci) { copyinfo* next = ci->next; if (ci->flag == 0) { fprintf(stderr, "pull: %s -> %s\n", ci->src, ci->dst); if (!sync_recv(sc, ci->src, ci->dst, false)) { sc.Print(android::base::StringPrintf("pull: %s -> %s", ci->src, ci->dst)); if (!sync_recv(sc, ci->src, ci->dst)) { return false; } Loading @@ -736,20 +752,22 @@ static bool copy_remote_dir_local(SyncConnection& sc, const char* rpath, const c ci = next; } fprintf(stderr, "%d file%s pulled. %d file%s skipped.\n", sc.Print(android::base::StringPrintf("%s: %d file%s pulled. %d file%s skipped.%s\n", rpath, pulled, (pulled == 1) ? "" : "s", skipped, (skipped == 1) ? "" : "s"); skipped, (skipped == 1) ? "" : "s", sc.TransferRate().c_str())); return true; } bool do_sync_pull(const char* rpath, const char* lpath, bool show_progress, int copy_attrs) { bool do_sync_pull(const char* rpath, const char* lpath, int copy_attrs) { SyncConnection sc; if (!sc.IsValid()) return false; unsigned mode, time; if (!sync_stat(sc, rpath, &time, &mode, nullptr)) return false; if (mode == 0) { fprintf(stderr, "adb: remote object '%s' does not exist\n", rpath); sc.Error("remote object '%s' does not exist", rpath); return false; } Loading @@ -764,25 +782,24 @@ bool do_sync_pull(const char* rpath, const char* lpath, bool show_progress, int lpath = path_holder.c_str(); } } if (!sync_recv(sc, rpath, lpath, show_progress)) { if (!sync_recv(sc, rpath, lpath)) { return false; } else { if (copy_attrs && set_time_and_mode(lpath, time, mode)) { return false; } } sc.Print("\n"); return true; } else if (S_ISDIR(mode)) { return copy_remote_dir_local(sc, rpath, lpath, copy_attrs); } fprintf(stderr, "adb: remote object '%s' not a file or directory\n", rpath); sc.Error("remote object '%s' not a file or directory", rpath); return false; } bool do_sync_sync(const std::string& lpath, const std::string& rpath, bool list_only) { fprintf(stderr, "syncing %s...\n", rpath.c_str()); SyncConnection sc; if (!sc.IsValid()) return false; Loading
adb/file_sync_service.h +2 −2 Original line number Diff line number Diff line Loading @@ -64,9 +64,9 @@ union syncmsg { void file_sync_service(int fd, void* cookie); bool do_sync_ls(const char* path); bool do_sync_push(const char* lpath, const char* rpath, bool show_progress); bool do_sync_push(const char* lpath, const char* rpath); bool do_sync_sync(const std::string& lpath, const std::string& rpath, bool list_only); bool do_sync_pull(const char* rpath, const char* lpath, bool show_progress, int copy_attrs); bool do_sync_pull(const char* rpath, const char* lpath, int copy_attrs); #define SYNC_DATA_MAX (64*1024) Loading