Loading tests/component/updater_test.cpp +39 −6 Original line number Diff line number Diff line Loading @@ -14,6 +14,10 @@ * limitations under the License. */ #include <sys/stat.h> #include <sys/types.h> #include <unistd.h> #include <string> #include <android-base/file.h> Loading Loading @@ -212,10 +216,15 @@ TEST_F(UpdaterTest, rename) { // Parents create successfully. TemporaryFile temp_file3; TemporaryDir td; std::string temp_dir = std::string(td.path) + "/aaa/bbb/a.txt"; std::string script3("rename(\"" + std::string(temp_file3.path) + "\", \"" + temp_dir + "\")"); expect(temp_dir.c_str(), script3.c_str(), kNoCause); std::string temp_dir(td.path); std::string dst_file = temp_dir + "/aaa/bbb/a.txt"; std::string script3("rename(\"" + std::string(temp_file3.path) + "\", \"" + dst_file + "\")"); expect(dst_file.c_str(), script3.c_str(), kNoCause); // Clean up the temp files under td. ASSERT_EQ(0, unlink(dst_file.c_str())); ASSERT_EQ(0, rmdir((temp_dir + "/aaa/bbb").c_str())); ASSERT_EQ(0, rmdir((temp_dir + "/aaa").c_str())); } TEST_F(UpdaterTest, symlink) { Loading @@ -227,7 +236,31 @@ TEST_F(UpdaterTest, symlink) { std::string script1("symlink(\"" + std::string(temp_file1.path) + "\", \"\")"); expect(nullptr, script1.c_str(), kSymlinkFailure); // symlink failed to remove old src. std::string script2("symlink(\"" + std::string(temp_file1.path) + "\", \"/proc\")"); std::string script2("symlink(\"" + std::string(temp_file1.path) + "\", \"src1\", \"\")"); expect(nullptr, script2.c_str(), kSymlinkFailure); // symlink failed to remove old src. std::string script3("symlink(\"" + std::string(temp_file1.path) + "\", \"/proc\")"); expect(nullptr, script3.c_str(), kSymlinkFailure); // symlink can create symlinks. TemporaryFile temp_file; std::string content = "magicvalue"; ASSERT_TRUE(android::base::WriteStringToFile(content, temp_file.path)); TemporaryDir td; std::string src1 = std::string(td.path) + "/symlink1"; std::string src2 = std::string(td.path) + "/symlink2"; std::string script4("symlink(\"" + std::string(temp_file.path) + "\", \"" + src1 + "\", \"" + src2 + "\")"); expect("t", script4.c_str(), kNoCause); // Verify the created symlinks. struct stat sb; ASSERT_TRUE(lstat(src1.c_str(), &sb) == 0 && S_ISLNK(sb.st_mode)); ASSERT_TRUE(lstat(src2.c_str(), &sb) == 0 && S_ISLNK(sb.st_mode)); // Clean up the leftovers. ASSERT_EQ(0, unlink(src1.c_str())); ASSERT_EQ(0, unlink(src2.c_str())); } updater/install.cpp +17 −20 Original line number Diff line number Diff line Loading @@ -566,8 +566,9 @@ Value* PackageExtractFileFn(const char* name, State* state, } } // symlink target src1 src2 ... // unlinks any previously existing src1, src2, etc before creating symlinks. // symlink(target, [src1, src2, ...]) // Creates all sources as symlinks to target. It unlinks any previously existing src1, src2, etc // before creating symlinks. Value* SymlinkFn(const char* name, State* state, int argc, Expr* argv[]) { if (argc == 0) { return ErrorAbort(state, kArgsParsingFailure, "%s() expects 1+ args, got %d", name, argc); Loading @@ -579,33 +580,29 @@ Value* SymlinkFn(const char* name, State* state, int argc, Expr* argv[]) { std::vector<std::string> srcs; if (!ReadArgs(state, argc-1, argv+1, &srcs)) { return ErrorAbort(state, kArgsParsingFailure, "%s() Failed to parse the argument(s)", name); return ErrorAbort(state, kArgsParsingFailure, "%s(): Failed to parse the argument(s)", name); } int bad = 0; for (int i = 0; i < argc-1; ++i) { if (unlink(srcs[i].c_str()) < 0) { if (errno != ENOENT) { printf("%s: failed to remove %s: %s\n", name, srcs[i].c_str(), strerror(errno)); size_t bad = 0; for (const auto& src : srcs) { if (unlink(src.c_str()) == -1 && errno != ENOENT) { printf("%s: failed to remove %s: %s\n", name, src.c_str(), strerror(errno)); ++bad; } } if (!make_parents(srcs[i])) { } else if (!make_parents(src)) { printf("%s: failed to symlink %s to %s: making parents failed\n", name, srcs[i].c_str(), target.c_str()); name, src.c_str(), target.c_str()); ++bad; } if (symlink(target.c_str(), srcs[i].c_str()) < 0) { } else if (symlink(target.c_str(), src.c_str()) == -1) { printf("%s: failed to symlink %s to %s: %s\n", name, srcs[i].c_str(), target.c_str(), strerror(errno)); name, src.c_str(), target.c_str(), strerror(errno)); ++bad; } } if (bad) { return ErrorAbort(state, kSymlinkFailure, "%s: some symlinks failed", name); if (bad != 0) { return ErrorAbort(state, kSymlinkFailure, "%s: Failed to create %zu symlink(s)", name, bad); } return StringValue(""); return StringValue("t"); } struct perm_parsed_args { Loading Loading
tests/component/updater_test.cpp +39 −6 Original line number Diff line number Diff line Loading @@ -14,6 +14,10 @@ * limitations under the License. */ #include <sys/stat.h> #include <sys/types.h> #include <unistd.h> #include <string> #include <android-base/file.h> Loading Loading @@ -212,10 +216,15 @@ TEST_F(UpdaterTest, rename) { // Parents create successfully. TemporaryFile temp_file3; TemporaryDir td; std::string temp_dir = std::string(td.path) + "/aaa/bbb/a.txt"; std::string script3("rename(\"" + std::string(temp_file3.path) + "\", \"" + temp_dir + "\")"); expect(temp_dir.c_str(), script3.c_str(), kNoCause); std::string temp_dir(td.path); std::string dst_file = temp_dir + "/aaa/bbb/a.txt"; std::string script3("rename(\"" + std::string(temp_file3.path) + "\", \"" + dst_file + "\")"); expect(dst_file.c_str(), script3.c_str(), kNoCause); // Clean up the temp files under td. ASSERT_EQ(0, unlink(dst_file.c_str())); ASSERT_EQ(0, rmdir((temp_dir + "/aaa/bbb").c_str())); ASSERT_EQ(0, rmdir((temp_dir + "/aaa").c_str())); } TEST_F(UpdaterTest, symlink) { Loading @@ -227,7 +236,31 @@ TEST_F(UpdaterTest, symlink) { std::string script1("symlink(\"" + std::string(temp_file1.path) + "\", \"\")"); expect(nullptr, script1.c_str(), kSymlinkFailure); // symlink failed to remove old src. std::string script2("symlink(\"" + std::string(temp_file1.path) + "\", \"/proc\")"); std::string script2("symlink(\"" + std::string(temp_file1.path) + "\", \"src1\", \"\")"); expect(nullptr, script2.c_str(), kSymlinkFailure); // symlink failed to remove old src. std::string script3("symlink(\"" + std::string(temp_file1.path) + "\", \"/proc\")"); expect(nullptr, script3.c_str(), kSymlinkFailure); // symlink can create symlinks. TemporaryFile temp_file; std::string content = "magicvalue"; ASSERT_TRUE(android::base::WriteStringToFile(content, temp_file.path)); TemporaryDir td; std::string src1 = std::string(td.path) + "/symlink1"; std::string src2 = std::string(td.path) + "/symlink2"; std::string script4("symlink(\"" + std::string(temp_file.path) + "\", \"" + src1 + "\", \"" + src2 + "\")"); expect("t", script4.c_str(), kNoCause); // Verify the created symlinks. struct stat sb; ASSERT_TRUE(lstat(src1.c_str(), &sb) == 0 && S_ISLNK(sb.st_mode)); ASSERT_TRUE(lstat(src2.c_str(), &sb) == 0 && S_ISLNK(sb.st_mode)); // Clean up the leftovers. ASSERT_EQ(0, unlink(src1.c_str())); ASSERT_EQ(0, unlink(src2.c_str())); }
updater/install.cpp +17 −20 Original line number Diff line number Diff line Loading @@ -566,8 +566,9 @@ Value* PackageExtractFileFn(const char* name, State* state, } } // symlink target src1 src2 ... // unlinks any previously existing src1, src2, etc before creating symlinks. // symlink(target, [src1, src2, ...]) // Creates all sources as symlinks to target. It unlinks any previously existing src1, src2, etc // before creating symlinks. Value* SymlinkFn(const char* name, State* state, int argc, Expr* argv[]) { if (argc == 0) { return ErrorAbort(state, kArgsParsingFailure, "%s() expects 1+ args, got %d", name, argc); Loading @@ -579,33 +580,29 @@ Value* SymlinkFn(const char* name, State* state, int argc, Expr* argv[]) { std::vector<std::string> srcs; if (!ReadArgs(state, argc-1, argv+1, &srcs)) { return ErrorAbort(state, kArgsParsingFailure, "%s() Failed to parse the argument(s)", name); return ErrorAbort(state, kArgsParsingFailure, "%s(): Failed to parse the argument(s)", name); } int bad = 0; for (int i = 0; i < argc-1; ++i) { if (unlink(srcs[i].c_str()) < 0) { if (errno != ENOENT) { printf("%s: failed to remove %s: %s\n", name, srcs[i].c_str(), strerror(errno)); size_t bad = 0; for (const auto& src : srcs) { if (unlink(src.c_str()) == -1 && errno != ENOENT) { printf("%s: failed to remove %s: %s\n", name, src.c_str(), strerror(errno)); ++bad; } } if (!make_parents(srcs[i])) { } else if (!make_parents(src)) { printf("%s: failed to symlink %s to %s: making parents failed\n", name, srcs[i].c_str(), target.c_str()); name, src.c_str(), target.c_str()); ++bad; } if (symlink(target.c_str(), srcs[i].c_str()) < 0) { } else if (symlink(target.c_str(), src.c_str()) == -1) { printf("%s: failed to symlink %s to %s: %s\n", name, srcs[i].c_str(), target.c_str(), strerror(errno)); name, src.c_str(), target.c_str(), strerror(errno)); ++bad; } } if (bad) { return ErrorAbort(state, kSymlinkFailure, "%s: some symlinks failed", name); if (bad != 0) { return ErrorAbort(state, kSymlinkFailure, "%s: Failed to create %zu symlink(s)", name, bad); } return StringValue(""); return StringValue("t"); } struct perm_parsed_args { Loading