Merge "adb: C++ify local_build_list and remote_build_list."
diff --git a/adb/file_sync_client.cpp b/adb/file_sync_client.cpp
index 7a60580..56859b5 100644
--- a/adb/file_sync_client.cpp
+++ b/adb/file_sync_client.cpp
@@ -28,6 +28,7 @@
#include <unistd.h>
#include <utime.h>
+#include <functional>
#include <memory>
#include <vector>
@@ -230,9 +231,10 @@
}
};
-typedef void (*sync_ls_cb)(unsigned mode, unsigned size, unsigned time, const char* name, void* cookie);
+typedef void (sync_ls_cb)(unsigned mode, unsigned size, unsigned time, const char* name);
-static bool sync_ls(SyncConnection& sc, const char* path, sync_ls_cb func, void* cookie) {
+static bool sync_ls(SyncConnection& sc, const char* path,
+ std::function<sync_ls_cb> func) {
if (!sc.SendRequest(ID_LIST, path)) return false;
while (true) {
@@ -249,7 +251,7 @@
if (!ReadFdExactly(sc.fd, buf, len)) return false;
buf[len] = 0;
- func(msg.dent.mode, msg.dent.size, msg.dent.time, buf, cookie);
+ func(msg.dent.mode, msg.dent.size, msg.dent.time, buf);
}
}
@@ -448,65 +450,45 @@
return true;
}
-static void do_sync_ls_cb(unsigned mode, unsigned size, unsigned time,
- const char* name, void* /*cookie*/) {
- printf("%08x %08x %08x %s\n", mode, size, time, name);
-}
-
bool do_sync_ls(const char* path) {
SyncConnection sc;
if (!sc.IsValid()) return false;
- return sync_ls(sc, path, do_sync_ls_cb, 0);
+ return sync_ls(sc, path, [](unsigned mode, unsigned size, unsigned time,
+ const char* name) {
+ printf("%08x %08x %08x %s\n", mode, size, time, name);
+ });
}
struct copyinfo
{
- copyinfo *next;
- const char *src;
- const char *dst;
+ std::string src;
+ std::string dst;
unsigned int time;
unsigned int mode;
uint64_t size;
int flag;
};
-static copyinfo* mkcopyinfo(const char* spath, const char* dpath, const char* name, int isdir) {
- int slen = strlen(spath);
- int dlen = strlen(dpath);
- int nlen = strlen(name);
- int ssize = slen + nlen + 2;
- int dsize = dlen + nlen + 2;
-
- copyinfo *ci = reinterpret_cast<copyinfo*>(malloc(sizeof(copyinfo) + ssize + dsize));
- if (ci == 0) {
- fprintf(stderr, "out of memory\n");
- abort();
- }
-
- ci->next = 0;
- ci->time = 0;
- ci->mode = 0;
- ci->size = 0;
- ci->flag = 0;
- ci->src = (const char*)(ci + 1);
- ci->dst = ci->src + ssize;
- snprintf((char*) ci->src, ssize, isdir ? "%s%s/" : "%s%s", spath, name);
- snprintf((char*) ci->dst, dsize, isdir ? "%s%s/" : "%s%s", dpath, name);
-
- return ci;
+static copyinfo mkcopyinfo(const char* spath, const char* dpath, const char* name, bool isdir) {
+ copyinfo result;
+ result.src = android::base::StringPrintf(isdir ? "%s%s/" : "%s%s", spath, name);
+ result.dst = android::base::StringPrintf(isdir ? "%s%s/" : "%s%s", dpath, name);
+ result.time = 0;
+ result.mode = 0;
+ result.size = 0;
+ result.flag = 0;
+ return result;
}
static bool IsDotOrDotDot(const char* name) {
return name[0] == '.' && (name[1] == '\0' || (name[1] == '.' && name[2] == '\0'));
}
-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);
+static int local_build_list(SyncConnection& sc, std::vector<copyinfo>* filelist,
+ const char* lpath, const char* rpath) {
+ std::vector<copyinfo> dirlist;
+ std::unique_ptr<DIR, int (*)(DIR*)> dir(opendir(lpath), closedir);
if (!dir) {
sc.Error("cannot open '%s': %s", lpath, strerror(errno));
return -1;
@@ -527,33 +509,27 @@
struct stat st;
if (!lstat(stat_path, &st)) {
if (S_ISDIR(st.st_mode)) {
- ci = mkcopyinfo(lpath, rpath, de->d_name, 1);
- ci->next = dirlist;
- dirlist = ci;
+ dirlist.push_back(mkcopyinfo(lpath, rpath, de->d_name, 1));
} else {
- ci = mkcopyinfo(lpath, rpath, de->d_name, 0);
if (!S_ISREG(st.st_mode) && !S_ISLNK(st.st_mode)) {
- sc.Error("skipping special file '%s'", ci->src);
- free(ci);
+ sc.Error("skipping special file '%s'", lpath);
} else {
- ci->time = st.st_mtime;
- ci->mode = st.st_mode;
- ci->size = st.st_size;
- ci->next = *filelist;
- *filelist = ci;
+ copyinfo ci = mkcopyinfo(lpath, rpath, de->d_name, 0);
+ ci.time = st.st_mtime;
+ ci.mode = st.st_mode;
+ ci.size = st.st_size;
+ filelist->push_back(ci);
}
}
} else {
- sc.Error("cannot lstat '%s': %s",stat_path , strerror(errno));
+ sc.Error("cannot lstat '%s': %s", stat_path, strerror(errno));
}
}
// Close this directory and recurse.
dir.reset();
- for (ci = dirlist; ci != 0; ci = next) {
- next = ci->next;
- local_build_list(sc, filelist, ci->src, ci->dst);
- free(ci);
+ for (const copyinfo& ci : dirlist) {
+ local_build_list(sc, filelist, ci.src.c_str(), ci.dst.c_str());
}
return 0;
@@ -561,8 +537,7 @@
static bool copy_local_dir_remote(SyncConnection& sc, const char* lpath, const char* rpath,
bool check_timestamps, bool list_only) {
- copyinfo *filelist = 0;
- copyinfo *ci, *next;
+ std::vector<copyinfo> filelist;
int pushed = 0;
int skipped = 0;
@@ -587,28 +562,29 @@
}
if (check_timestamps) {
- for (ci = filelist; ci != 0; ci = ci->next) {
- if (!sc.SendRequest(ID_STAT, ci->dst)) return false;
+ for (const copyinfo& ci : filelist) {
+ if (!sc.SendRequest(ID_STAT, ci.dst.c_str())) return false;
}
- for(ci = filelist; ci != 0; ci = ci->next) {
+ for (copyinfo& ci : filelist) {
unsigned int timestamp, mode, size;
if (!sync_finish_stat(sc, ×tamp, &mode, &size)) return false;
- if (size == ci->size) {
+ if (size == ci.size) {
/* for links, we cannot update the atime/mtime */
- if ((S_ISREG(ci->mode & mode) && timestamp == ci->time) ||
- (S_ISLNK(ci->mode & mode) && timestamp >= ci->time)) {
- ci->flag = 1;
+ if ((S_ISREG(ci.mode & mode) && timestamp == ci.time) ||
+ (S_ISLNK(ci.mode & mode) && timestamp >= ci.time)) {
+ ci.flag = 1;
}
}
}
}
- for (ci = filelist; ci != 0; ci = next) {
- next = ci->next;
- if (ci->flag == 0) {
+
+ for (const copyinfo& ci : filelist) {
+ if (ci.flag == 0) {
if (list_only) {
- fprintf(stderr, "would push: %s -> %s\n", ci->src, ci->dst);
+ fprintf(stderr, "would push: %s -> %s\n", ci.src.c_str(),
+ ci.dst.c_str());
} else {
- if (!sync_send(sc, ci->src, ci->dst, ci->time, ci->mode)) {
+ if (!sync_send(sc, ci.src.c_str(), ci.dst.c_str(), ci.time, ci.mode)) {
return false;
}
}
@@ -616,7 +592,6 @@
} else {
skipped++;
}
- free(ci);
}
sc.Printf("%s: %d file%s pushed. %d file%s skipped.%s\n", rpath, pushed,
@@ -676,67 +651,43 @@
return success;
}
-struct sync_ls_build_list_cb_args {
- SyncConnection* sc;
- copyinfo** filelist;
- copyinfo** dirlist;
- const char* rpath;
- const char* lpath;
-};
-
-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 = static_cast<sync_ls_build_list_cb_args*>(cookie);
- copyinfo *ci;
-
- if (S_ISDIR(mode)) {
- copyinfo **dirlist = args->dirlist;
-
- // Don't try recursing down "." or "..".
- if (IsDotOrDotDot(name)) return;
-
- ci = mkcopyinfo(args->rpath, args->lpath, name, 1);
- ci->next = *dirlist;
- *dirlist = ci;
- } else if (S_ISREG(mode) || S_ISLNK(mode)) {
- copyinfo **filelist = args->filelist;
-
- ci = mkcopyinfo(args->rpath, args->lpath, name, 0);
- ci->time = time;
- ci->mode = mode;
- ci->size = size;
- ci->next = *filelist;
- *filelist = ci;
- } else {
- args->sc->Printf("skipping special file '%s'\n", name);
- }
-}
-
-static bool remote_build_list(SyncConnection& sc, copyinfo **filelist,
- const char *rpath, const char *lpath) {
- copyinfo* dirlist = nullptr;
-
- sync_ls_build_list_cb_args args;
- args.sc = ≻
- args.filelist = filelist;
- args.dirlist = &dirlist;
- args.rpath = rpath;
- args.lpath = lpath;
+static bool remote_build_list(SyncConnection& sc,
+ std::vector<copyinfo>* filelist,
+ const char* rpath, const char* lpath) {
+ std::vector<copyinfo> dirlist;
// Put the files/dirs in rpath on the lists.
- if (!sync_ls(sc, rpath, sync_ls_build_list_cb, &args)) {
+ auto callback = [&](unsigned mode, unsigned size, unsigned time,
+ const char* name) {
+ if (S_ISDIR(mode)) {
+ // Don't try recursing down "." or "..".
+ if (IsDotOrDotDot(name)) return;
+
+ dirlist.push_back(mkcopyinfo(rpath, lpath, name, 1));
+ } else if (S_ISREG(mode) || S_ISLNK(mode)) {
+ copyinfo ci = mkcopyinfo(rpath, lpath, name, 0);
+ ci.time = time;
+ ci.mode = mode;
+ ci.size = size;
+ filelist->push_back(ci);
+ } else {
+ sc.Print(android::base::StringPrintf("skipping special file '%s'\n",
+ name));
+ }
+ };
+
+ if (!sync_ls(sc, rpath, callback)) {
return false;
}
// Recurse into each directory we found.
- while (dirlist != NULL) {
- copyinfo* next = dirlist->next;
- if (!remote_build_list(sc, filelist, dirlist->src, dirlist->dst)) {
+ while (!dirlist.empty()) {
+ copyinfo current = dirlist.back();
+ dirlist.pop_back();
+ if (!remote_build_list(sc, filelist, current.src.c_str(),
+ current.dst.c_str())) {
return false;
}
- free(dirlist);
- dirlist = next;
}
return true;
@@ -748,7 +699,7 @@
int r1 = utime(lpath, ×);
/* use umask for permissions */
- mode_t mask=umask(0000);
+ mode_t mask = umask(0000);
umask(mask);
int r2 = chmod(lpath, mode & ~mask);
@@ -766,29 +717,29 @@
// Recursively build the list of files to copy.
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;
+ std::vector<copyinfo> filelist;
+ if (!remote_build_list(sc, &filelist, rpath_clean.c_str(),
+ lpath_clean.c_str())) {
+ return false;
+ }
int pulled = 0;
int skipped = 0;
- copyinfo* ci = filelist;
- while (ci) {
- copyinfo* next = ci->next;
- if (ci->flag == 0) {
- sc.Printf("pull: %s -> %s", ci->src, ci->dst);
- if (!sync_recv(sc, ci->src, ci->dst)) {
+ for (const copyinfo &ci : filelist) {
+ if (ci.flag == 0) {
+ sc.Printf("pull: %s -> %s", ci.src.c_str(), ci.dst.c_str());
+ if (!sync_recv(sc, ci.src.c_str(), ci.dst.c_str())) {
return false;
}
- if (copy_attrs && set_time_and_mode(ci->dst, ci->time, ci->mode)) {
+ if (copy_attrs &&
+ set_time_and_mode(ci.dst.c_str(), ci.time, ci.mode)) {
return false;
}
pulled++;
} else {
skipped++;
}
- free(ci);
- ci = next;
}
sc.Printf("%s: %d file%s pulled. %d file%s skipped.%s\n", rpath, pulled,