Merge "updater: Fix a bug in DeleteFn()." am: 529032f4a0 am: 4f91ca78b9 am: 786b083b8e
am: afd1d3af5a

Change-Id: I91d664cdbe14b4b7d70090ba5aebab5a46b57c1c
diff --git a/tests/component/updater_test.cpp b/tests/component/updater_test.cpp
index bd1df55..337769e 100644
--- a/tests/component/updater_test.cpp
+++ b/tests/component/updater_test.cpp
@@ -147,3 +147,36 @@
                        "\", \"ro.product.model\")");
     expect("", script6.c_str(), kNoCause);
 }
+
+TEST_F(UpdaterTest, delete) {
+    // Delete none.
+    expect("0", "delete()", kNoCause);
+    expect("0", "delete(\"/doesntexist\")", kNoCause);
+    expect("0", "delete(\"/doesntexist1\", \"/doesntexist2\")", kNoCause);
+    expect("0", "delete(\"/doesntexist1\", \"/doesntexist2\", \"/doesntexist3\")", kNoCause);
+
+    // Delete one file.
+    TemporaryFile temp_file1;
+    ASSERT_TRUE(android::base::WriteStringToFile("abc", temp_file1.path));
+    std::string script1("delete(\"" + std::string(temp_file1.path) + "\")");
+    expect("1", script1.c_str(), kNoCause);
+
+    // Delete two files.
+    TemporaryFile temp_file2;
+    ASSERT_TRUE(android::base::WriteStringToFile("abc", temp_file2.path));
+    TemporaryFile temp_file3;
+    ASSERT_TRUE(android::base::WriteStringToFile("abc", temp_file3.path));
+    std::string script2("delete(\"" + std::string(temp_file2.path) + "\", \"" +
+                        std::string(temp_file3.path) + "\")");
+    expect("2", script2.c_str(), kNoCause);
+
+    // Delete already deleted files.
+    expect("0", script2.c_str(), kNoCause);
+
+    // Delete one out of three.
+    TemporaryFile temp_file4;
+    ASSERT_TRUE(android::base::WriteStringToFile("abc", temp_file4.path));
+    std::string script3("delete(\"/doesntexist1\", \"" + std::string(temp_file4.path) +
+                        "\", \"/doesntexist2\")");
+    expect("1", script3.c_str(), kNoCause);
+}
diff --git a/updater/install.cpp b/updater/install.cpp
index 19ba365..25f6a91 100644
--- a/updater/install.cpp
+++ b/updater/install.cpp
@@ -66,7 +66,7 @@
 
 // Send over the buffer to recovery though the command pipe.
 static void uiPrint(State* state, const std::string& buffer) {
-    UpdaterInfo* ui = reinterpret_cast<UpdaterInfo*>(state->cookie);
+    UpdaterInfo* ui = static_cast<UpdaterInfo*>(state->cookie);
 
     // "line1\nline2\n" will be split into 3 tokens: "line1", "line2" and "".
     // So skip sending empty strings to UI.
@@ -117,6 +117,7 @@
 }
 
 // mount(fs_type, partition_type, location, mount_point)
+// mount(fs_type, partition_type, location, mount_point, mount_options)
 //
 //    fs_type="ext4"   partition_type="EMMC"    location=device
 Value* MountFn(const char* name, State* state, int argc, Expr* argv[]) {
@@ -252,7 +253,6 @@
     return WEXITSTATUS(status);
 }
 
-
 // format(fs_type, partition_type, location, fs_size, mount_point)
 //
 //    fs_type="ext4"   partition_type="EMMC"    location=device    fs_size=<bytes> mount_point=<location>
@@ -301,14 +301,13 @@
     if (fs_type == "ext4") {
         int status = make_ext4fs(location.c_str(), size, mount_point.c_str(), sehandle);
         if (status != 0) {
-            printf("%s: make_ext4fs failed (%d) on %s",
-                    name, status, location.c_str());
+            printf("%s: make_ext4fs failed (%d) on %s", name, status, location.c_str());
             return StringValue("");
         }
         return StringValue(location);
     } else if (fs_type == "f2fs") {
         if (size < 0) {
-            printf("fs_size can't be negative for f2fs: %s", fs_size.c_str());
+            printf("%s: fs_size can't be negative for f2fs: %s", name, fs_size.c_str());
             return StringValue("");
         }
         std::string num_sectors = std::to_string(size / 512);
@@ -318,8 +317,7 @@
                 num_sectors.c_str(), nullptr};
         int status = exec_cmd(f2fs_path, (char* const*)f2fs_argv);
         if (status != 0) {
-            printf("%s: mkfs.f2fs failed (%d) on %s",
-                    name, status, location.c_str());
+            printf("%s: mkfs.f2fs failed (%d) on %s", name, status, location.c_str());
             return StringValue("");
         }
         return StringValue(location);
@@ -365,8 +363,14 @@
     return StringValue(dst_name);
 }
 
+// delete([filename, ...])
+//   Deletes all the filenames listed. Returns the number of files successfully deleted.
+//
+// delete_recursive([dirname, ...])
+//   Recursively deletes dirnames and all their contents. Returns the number of directories
+//   successfully deleted.
 Value* DeleteFn(const char* name, State* state, int argc, Expr* argv[]) {
-    std::vector<std::string> paths;
+    std::vector<std::string> paths(argc);
     for (int i = 0; i < argc; ++i) {
         if (!Evaluate(state, argv[i], &paths[i])) {
             return nullptr;
@@ -382,7 +386,7 @@
         }
     }
 
-    return StringValue(android::base::StringPrintf("%d", success));
+    return StringValue(std::to_string(success));
 }