init: add a copy_per_line built-in command
There are sysfs nodes that don't take multiple inputs, adding a new
copy_per_line built-in command to copy from source file to destination
line by line.
Bug: 171740453
Test: boot and check file and log
Change-Id: I41b7a565829299d56b81d4509525dfa6a0a52444
diff --git a/init/README.md b/init/README.md
index ab6a885..bcbbfbb 100644
--- a/init/README.md
+++ b/init/README.md
@@ -451,6 +451,10 @@
exist. And it will be truncated if dst file is a normal regular file and
already exists.
+`copy_per_line <src> <dst>`
+> Copies a file line by line. Similar to copy, but useful for dst is a sysfs node
+ that doesn't handle multiple lines of data.
+
`domainname <name>`
> Set the domain name.
diff --git a/init/builtins.cpp b/init/builtins.cpp
index d00d1b1..b235d2f 100644
--- a/init/builtins.cpp
+++ b/init/builtins.cpp
@@ -88,6 +88,7 @@
using android::base::Basename;
using android::base::SetProperty;
+using android::base::Split;
using android::base::StartsWith;
using android::base::StringPrintf;
using android::base::unique_fd;
@@ -968,6 +969,23 @@
return {};
}
+static Result<void> do_copy_per_line(const BuiltinArguments& args) {
+ std::string file_contents;
+ if (!android::base::ReadFileToString(args[1], &file_contents, true)) {
+ return Error() << "Could not read input file '" << args[1] << "'";
+ }
+ auto lines = Split(file_contents, "\n");
+ for (const auto& line : lines) {
+ auto result = WriteFile(args[2], line);
+ if (!result.ok()) {
+ LOG(VERBOSE) << "Could not write to output file '" << args[2] << "' with '" << line
+ << "' : " << result.error();
+ }
+ }
+
+ return {};
+}
+
static Result<void> do_chown(const BuiltinArguments& args) {
auto uid = DecodeUid(args[1]);
if (!uid.ok()) {
@@ -1366,6 +1384,7 @@
{"class_start_post_data", {1, 1, {false, do_class_start_post_data}}},
{"class_stop", {1, 1, {false, do_class_stop}}},
{"copy", {2, 2, {true, do_copy}}},
+ {"copy_per_line", {2, 2, {true, do_copy_per_line}}},
{"domainname", {1, 1, {true, do_domainname}}},
{"enable", {1, 1, {false, do_enable}}},
{"exec", {1, kMax, {false, do_exec}}},