diff options
Diffstat (limited to 'init')
-rw-r--r-- | init/action.cpp | 92 | ||||
-rw-r--r-- | init/action.h | 7 | ||||
-rw-r--r-- | init/action_manager.cpp | 8 | ||||
-rw-r--r-- | init/action_parser.cpp | 93 | ||||
-rw-r--r-- | init/service.cpp | 7 |
5 files changed, 107 insertions, 100 deletions
diff --git a/init/action.cpp b/init/action.cpp index 05b484f51..11335ca14 100644 --- a/init/action.cpp +++ b/init/action.cpp @@ -21,11 +21,9 @@ #include <android-base/properties.h> #include <android-base/strings.h> -#include "stable_properties.h" #include "util.h" using android::base::Join; -using android::base::StartsWith; namespace android { namespace init { @@ -70,8 +68,15 @@ std::string Command::BuildCommandString() const { return Join(args_, ' '); } -Action::Action(bool oneshot, Subcontext* subcontext, const std::string& filename, int line) - : oneshot_(oneshot), subcontext_(subcontext), filename_(filename), line_(line) {} +Action::Action(bool oneshot, Subcontext* subcontext, const std::string& filename, int line, + const std::string& event_trigger, + const std::map<std::string, std::string>& property_triggers) + : property_triggers_(property_triggers), + event_trigger_(event_trigger), + oneshot_(oneshot), + subcontext_(subcontext), + filename_(filename), + line_(line) {} const KeywordFunctionMap* Action::function_map_ = nullptr; @@ -135,85 +140,6 @@ void Action::ExecuteCommand(const Command& command) const { } } -static bool IsActionableProperty(Subcontext* subcontext, const std::string& prop_name) { - static bool enabled = - android::base::GetBoolProperty("ro.actionable_compatible_property.enabled", false); - - if (subcontext == nullptr || !enabled) { - return true; - } - - if (kExportedActionableProperties.count(prop_name) == 1) { - return true; - } - for (const auto& prefix : kPartnerPrefixes) { - if (android::base::StartsWith(prop_name, prefix)) { - return true; - } - } - return false; -} - -Result<Success> Action::ParsePropertyTrigger(const std::string& trigger) { - const static std::string prop_str("property:"); - std::string prop_name(trigger.substr(prop_str.length())); - size_t equal_pos = prop_name.find('='); - if (equal_pos == std::string::npos) { - return Error() << "property trigger found without matching '='"; - } - - std::string prop_value(prop_name.substr(equal_pos + 1)); - prop_name.erase(equal_pos); - - if (!IsActionableProperty(subcontext_, prop_name)) { - return Error() << "unexported property tigger found: " << prop_name; - } - - if (auto [it, inserted] = property_triggers_.emplace(prop_name, prop_value); !inserted) { - return Error() << "multiple property triggers found for same property"; - } - return Success(); -} - -Result<Success> Action::InitTriggers(const std::vector<std::string>& args) { - const static std::string prop_str("property:"); - for (std::size_t i = 0; i < args.size(); ++i) { - if (args[i].empty()) { - return Error() << "empty trigger is not valid"; - } - - if (i % 2) { - if (args[i] != "&&") { - return Error() << "&& is the only symbol allowed to concatenate actions"; - } else { - continue; - } - } - - if (!args[i].compare(0, prop_str.length(), prop_str)) { - if (auto result = ParsePropertyTrigger(args[i]); !result) { - return result; - } - } else { - if (!event_trigger_.empty()) { - return Error() << "multiple event triggers are not allowed"; - } - - event_trigger_ = args[i]; - } - } - - return Success(); -} - -Result<Success> Action::InitSingleTrigger(const std::string& trigger) { - std::vector<std::string> name_vector{trigger}; - if (auto result = InitTriggers(name_vector); !result) { - return Error() << "InitTriggers() failed: " << result.error(); - } - return Success(); -} - // This function checks that all property triggers are satisfied, that is // for each (name, value) in property_triggers_, check that the current // value of the property 'name' == value. diff --git a/init/action.h b/init/action.h index 2a6f36a59..4f063cc54 100644 --- a/init/action.h +++ b/init/action.h @@ -57,12 +57,12 @@ using BuiltinAction = class Action*; class Action { public: - Action(bool oneshot, Subcontext* subcontext, const std::string& filename, int line); + Action(bool oneshot, Subcontext* subcontext, const std::string& filename, int line, + const std::string& event_trigger, + const std::map<std::string, std::string>& property_triggers); Result<Success> AddCommand(const std::vector<std::string>& args, int line); void AddCommand(BuiltinFunction f, const std::vector<std::string>& args, int line); - Result<Success> InitTriggers(const std::vector<std::string>& args); - Result<Success> InitSingleTrigger(const std::string& trigger); std::size_t NumCommands() const; void ExecuteOneCommand(std::size_t command) const; void ExecuteAllCommands() const; @@ -83,7 +83,6 @@ class Action { void ExecuteCommand(const Command& command) const; bool CheckPropertyTriggers(const std::string& name = "", const std::string& value = "") const; - Result<Success> ParsePropertyTrigger(const std::string& trigger); std::map<std::string, std::string> property_triggers_; std::string event_trigger_; diff --git a/init/action_manager.cpp b/init/action_manager.cpp index 7e0359052..22977bb29 100644 --- a/init/action_manager.cpp +++ b/init/action_manager.cpp @@ -45,14 +45,10 @@ void ActionManager::QueueAllPropertyActions() { } void ActionManager::QueueBuiltinAction(BuiltinFunction func, const std::string& name) { - auto action = std::make_unique<Action>(true, nullptr, "<Builtin Action>", 0); + auto action = std::make_unique<Action>(true, nullptr, "<Builtin Action>", 0, name, + std::map<std::string, std::string>{}); std::vector<std::string> name_vector{name}; - if (auto result = action->InitSingleTrigger(name); !result) { - LOG(ERROR) << "Cannot queue BuiltinAction for " << name << ": " << result.error(); - return; - } - action->AddCommand(func, name_vector, 0); event_queue_.emplace(action.get()); diff --git a/init/action_parser.cpp b/init/action_parser.cpp index fd085b82d..8a4b518f5 100644 --- a/init/action_parser.cpp +++ b/init/action_parser.cpp @@ -16,13 +16,95 @@ #include "action_parser.h" +#include <android-base/properties.h> #include <android-base/strings.h> +#include "stable_properties.h" + +using android::base::GetBoolProperty; using android::base::StartsWith; namespace android { namespace init { +namespace { + +bool IsActionableProperty(Subcontext* subcontext, const std::string& prop_name) { + static bool enabled = GetBoolProperty("ro.actionable_compatible_property.enabled", false); + + if (subcontext == nullptr || !enabled) { + return true; + } + + if (kExportedActionableProperties.count(prop_name) == 1) { + return true; + } + for (const auto& prefix : kPartnerPrefixes) { + if (android::base::StartsWith(prop_name, prefix)) { + return true; + } + } + return false; +} + +Result<Success> ParsePropertyTrigger(const std::string& trigger, Subcontext* subcontext, + std::map<std::string, std::string>* property_triggers) { + const static std::string prop_str("property:"); + std::string prop_name(trigger.substr(prop_str.length())); + size_t equal_pos = prop_name.find('='); + if (equal_pos == std::string::npos) { + return Error() << "property trigger found without matching '='"; + } + + std::string prop_value(prop_name.substr(equal_pos + 1)); + prop_name.erase(equal_pos); + + if (!IsActionableProperty(subcontext, prop_name)) { + return Error() << "unexported property tigger found: " << prop_name; + } + + if (auto [it, inserted] = property_triggers->emplace(prop_name, prop_value); !inserted) { + return Error() << "multiple property triggers found for same property"; + } + return Success(); +} + +Result<Success> ParseTriggers(const std::vector<std::string>& args, Subcontext* subcontext, + std::string* event_trigger, + std::map<std::string, std::string>* property_triggers) { + const static std::string prop_str("property:"); + for (std::size_t i = 0; i < args.size(); ++i) { + if (args[i].empty()) { + return Error() << "empty trigger is not valid"; + } + + if (i % 2) { + if (args[i] != "&&") { + return Error() << "&& is the only symbol allowed to concatenate actions"; + } else { + continue; + } + } + + if (!args[i].compare(0, prop_str.length(), prop_str)) { + if (auto result = ParsePropertyTrigger(args[i], subcontext, property_triggers); + !result) { + return result; + } + } else { + if (!event_trigger->empty()) { + return Error() << "multiple event triggers are not allowed"; + } + + *event_trigger = args[i]; + } + } + + return Success(); +} + +} // namespace + Result<Success> ActionParser::ParseSection(std::vector<std::string>&& args, const std::string& filename, int line) { std::vector<std::string> triggers(args.begin() + 1, args.end()); @@ -40,12 +122,17 @@ Result<Success> ActionParser::ParseSection(std::vector<std::string>&& args, } } - auto action = std::make_unique<Action>(false, action_subcontext, filename, line); + std::string event_trigger; + std::map<std::string, std::string> property_triggers; - if (auto result = action->InitTriggers(triggers); !result) { - return Error() << "InitTriggers() failed: " << result.error(); + if (auto result = ParseTriggers(triggers, action_subcontext, &event_trigger, &property_triggers); + !result) { + return Error() << "ParseTriggers() failed: " << result.error(); } + auto action = std::make_unique<Action>(false, action_subcontext, filename, line, event_trigger, + property_triggers); + action_ = std::move(action); return Success(); } diff --git a/init/service.cpp b/init/service.cpp index a4e33f7ec..7454a34ca 100644 --- a/init/service.cpp +++ b/init/service.cpp @@ -189,7 +189,8 @@ Service::Service(const std::string& name, unsigned flags, uid_t uid, gid_t gid, capabilities_(capabilities), namespace_flags_(namespace_flags), seclabel_(seclabel), - onrestart_(false, subcontext_for_restart_commands, "<Service '" + name + "' onrestart>", 0), + onrestart_(false, subcontext_for_restart_commands, "<Service '" + name + "' onrestart>", 0, + "onrestart", {}), keychord_id_(0), ioprio_class_(IoSchedClass_NONE), ioprio_pri_(0), @@ -199,9 +200,7 @@ Service::Service(const std::string& name, unsigned flags, uid_t uid, gid_t gid, soft_limit_in_bytes_(-1), limit_in_bytes_(-1), start_order_(0), - args_(args) { - onrestart_.InitSingleTrigger("onrestart"); -} + args_(args) {} void Service::NotifyStateChange(const std::string& new_state) const { if ((flags_ & SVC_TEMPORARY) != 0) { |