Merge "init: add exec_background command" am: 424ed42fb4
am: a6d75117e2
Change-Id: Ib912b0423493662faf6bc20718ef4f6e0d4fd545
diff --git a/init/README.md b/init/README.md
index 7df37ff..d7edf21 100644
--- a/init/README.md
+++ b/init/README.md
@@ -381,6 +381,11 @@
within _argument_.
Init halts executing commands until the forked process exits.
+`exec_background [ <seclabel> [ <user> [ <group>\* ] ] ] -- <command> [ <argument>\* ]`
+> Fork and execute command with the given arguments. This is handled similarly
+ to the `exec` command. The difference is that init does not halt executing
+ commands until the process exits for `exec_background`.
+
`exec_start <service>`
> Start a given service and halt the processing of additional init commands
until it returns. The command functions similarly to the `exec` command,
diff --git a/init/builtins.cpp b/init/builtins.cpp
index 96e78cb..0fef883 100644
--- a/init/builtins.cpp
+++ b/init/builtins.cpp
@@ -148,6 +148,19 @@
return Success();
}
+static Result<Success> do_exec_background(const std::vector<std::string>& args) {
+ auto service = Service::MakeTemporaryOneshotService(args);
+ if (!service) {
+ return Error() << "Could not create exec background service";
+ }
+ if (auto result = service->Start(); !result) {
+ return Error() << "Could not start exec background service: " << result.error();
+ }
+
+ ServiceList::GetInstance().AddService(std::move(service));
+ return Success();
+}
+
static Result<Success> do_exec_start(const std::vector<std::string>& args) {
Service* service = ServiceList::GetInstance().FindService(args[1]);
if (!service) {
@@ -978,6 +991,7 @@
{"domainname", {1, 1, do_domainname}},
{"enable", {1, 1, do_enable}},
{"exec", {1, kMax, do_exec}},
+ {"exec_background", {1, kMax, do_exec_background}},
{"exec_start", {1, 1, do_exec_start}},
{"export", {2, 2, do_export}},
{"hostname", {1, 1, do_hostname}},