init: use Result<T> for the parsing functions
Test: boot bullhead Merged-In: I7f00c5f0f54dd4fe05df73e1d6a89b56d788e113 Change-Id: I7f00c5f0f54dd4fe05df73e1d6a89b56d788e113
This commit is contained in:
parent
557946e57c
commit
89bcc85edf
12 changed files with 227 additions and 275 deletions
|
@ -53,19 +53,16 @@ Action::Action(bool oneshot, const std::string& filename, int line)
|
|||
|
||||
const KeywordMap<BuiltinFunction>* Action::function_map_ = nullptr;
|
||||
|
||||
bool Action::AddCommand(const std::vector<std::string>& args, int line, std::string* err) {
|
||||
Result<Success> Action::AddCommand(const std::vector<std::string>& args, int line) {
|
||||
if (!function_map_) {
|
||||
*err = "no function map available";
|
||||
return false;
|
||||
return Error() << "no function map available";
|
||||
}
|
||||
|
||||
auto function = function_map_->FindFunction(args, err);
|
||||
if (!function) {
|
||||
return false;
|
||||
}
|
||||
auto function = function_map_->FindFunction(args);
|
||||
if (!function) return Error() << function.error();
|
||||
|
||||
AddCommand(function, args, line);
|
||||
return true;
|
||||
AddCommand(*function, args, line);
|
||||
return Success();
|
||||
}
|
||||
|
||||
void Action::AddCommand(BuiltinFunction f, const std::vector<std::string>& args, int line) {
|
||||
|
@ -105,67 +102,60 @@ void Action::ExecuteCommand(const Command& command) const {
|
|||
}
|
||||
}
|
||||
|
||||
bool Action::ParsePropertyTrigger(const std::string& trigger, std::string* err) {
|
||||
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) {
|
||||
*err = "property trigger found without matching '='";
|
||||
return false;
|
||||
return Error() << "property trigger found without matching '='";
|
||||
}
|
||||
|
||||
std::string prop_value(prop_name.substr(equal_pos + 1));
|
||||
prop_name.erase(equal_pos);
|
||||
|
||||
if (auto [it, inserted] = property_triggers_.emplace(prop_name, prop_value); !inserted) {
|
||||
*err = "multiple property triggers found for same property";
|
||||
return false;
|
||||
return Error() << "multiple property triggers found for same property";
|
||||
}
|
||||
return true;
|
||||
return Success();
|
||||
}
|
||||
|
||||
bool Action::InitTriggers(const std::vector<std::string>& args, std::string* err) {
|
||||
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()) {
|
||||
*err = "empty trigger is not valid";
|
||||
return false;
|
||||
return Error() << "empty trigger is not valid";
|
||||
}
|
||||
|
||||
if (i % 2) {
|
||||
if (args[i] != "&&") {
|
||||
*err = "&& is the only symbol allowed to concatenate actions";
|
||||
return false;
|
||||
return Error() << "&& is the only symbol allowed to concatenate actions";
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (!args[i].compare(0, prop_str.length(), prop_str)) {
|
||||
if (!ParsePropertyTrigger(args[i], err)) {
|
||||
return false;
|
||||
if (auto result = ParsePropertyTrigger(args[i]); !result) {
|
||||
return result;
|
||||
}
|
||||
} else {
|
||||
if (!event_trigger_.empty()) {
|
||||
*err = "multiple event triggers are not allowed";
|
||||
return false;
|
||||
return Error() << "multiple event triggers are not allowed";
|
||||
}
|
||||
|
||||
event_trigger_ = args[i];
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
return Success();
|
||||
}
|
||||
|
||||
bool Action::InitSingleTrigger(const std::string& trigger) {
|
||||
Result<Success> Action::InitSingleTrigger(const std::string& trigger) {
|
||||
std::vector<std::string> name_vector{trigger};
|
||||
std::string err;
|
||||
bool ret = InitTriggers(name_vector, &err);
|
||||
if (!ret) {
|
||||
LOG(ERROR) << "InitSingleTrigger failed due to: " << err;
|
||||
if (auto result = InitTriggers(name_vector); !result) {
|
||||
return Error() << "InitTriggers() failed: " << result.error();
|
||||
}
|
||||
return ret;
|
||||
return Success();
|
||||
}
|
||||
|
||||
// This function checks that all property triggers are satisfied, that is
|
||||
|
@ -263,7 +253,8 @@ void ActionManager::QueueBuiltinAction(BuiltinFunction func, const std::string&
|
|||
auto action = std::make_unique<Action>(true, "<Builtin Action>", 0);
|
||||
std::vector<std::string> name_vector{name};
|
||||
|
||||
if (!action->InitSingleTrigger(name)) {
|
||||
if (auto result = action->InitSingleTrigger(name); !result) {
|
||||
LOG(ERROR) << "Cannot queue BuiltinAction for " << name << ": " << result.error();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -332,25 +323,25 @@ void ActionManager::ClearQueue() {
|
|||
current_command_ = 0;
|
||||
}
|
||||
|
||||
bool ActionParser::ParseSection(std::vector<std::string>&& args, const std::string& filename,
|
||||
int line, std::string* err) {
|
||||
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());
|
||||
if (triggers.size() < 1) {
|
||||
*err = "actions must have a trigger";
|
||||
return false;
|
||||
return Error() << "Actions must have a trigger";
|
||||
}
|
||||
|
||||
auto action = std::make_unique<Action>(false, filename, line);
|
||||
if (!action->InitTriggers(triggers, err)) {
|
||||
return false;
|
||||
|
||||
if (auto result = action->InitTriggers(triggers); !result) {
|
||||
return Error() << "InitTriggers() failed: " << result.error();
|
||||
}
|
||||
|
||||
action_ = std::move(action);
|
||||
return true;
|
||||
return Success();
|
||||
}
|
||||
|
||||
bool ActionParser::ParseLineSection(std::vector<std::string>&& args, int line, std::string* err) {
|
||||
return action_ ? action_->AddCommand(std::move(args), line, err) : false;
|
||||
Result<Success> ActionParser::ParseLineSection(std::vector<std::string>&& args, int line) {
|
||||
return action_ ? action_->AddCommand(std::move(args), line) : Success();
|
||||
}
|
||||
|
||||
void ActionParser::EndSection() {
|
||||
|
|
|
@ -54,10 +54,10 @@ class Action {
|
|||
public:
|
||||
explicit Action(bool oneshot, const std::string& filename, int line);
|
||||
|
||||
bool AddCommand(const std::vector<std::string>& args, int line, std::string* err);
|
||||
Result<Success> AddCommand(const std::vector<std::string>& args, int line);
|
||||
void AddCommand(BuiltinFunction f, const std::vector<std::string>& args, int line);
|
||||
bool InitTriggers(const std::vector<std::string>& args, std::string* err);
|
||||
bool InitSingleTrigger(const std::string& trigger);
|
||||
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;
|
||||
|
@ -79,7 +79,7 @@ private:
|
|||
void ExecuteCommand(const Command& command) const;
|
||||
bool CheckPropertyTriggers(const std::string& name = "",
|
||||
const std::string& value = "") const;
|
||||
bool ParsePropertyTrigger(const std::string& trigger, std::string* err);
|
||||
Result<Success> ParsePropertyTrigger(const std::string& trigger);
|
||||
|
||||
std::map<std::string, std::string> property_triggers_;
|
||||
std::string event_trigger_;
|
||||
|
@ -121,9 +121,9 @@ class ActionParser : public SectionParser {
|
|||
public:
|
||||
ActionParser(ActionManager* action_manager)
|
||||
: action_manager_(action_manager), action_(nullptr) {}
|
||||
bool ParseSection(std::vector<std::string>&& args, const std::string& filename, int line,
|
||||
std::string* err) override;
|
||||
bool ParseLineSection(std::vector<std::string>&& args, int line, std::string* err) override;
|
||||
Result<Success> ParseSection(std::vector<std::string>&& args, const std::string& filename,
|
||||
int line) override;
|
||||
Result<Success> ParseLineSection(std::vector<std::string>&& args, int line) override;
|
||||
void EndSection() override;
|
||||
|
||||
private:
|
||||
|
|
|
@ -23,24 +23,22 @@
|
|||
namespace android {
|
||||
namespace init {
|
||||
|
||||
bool ImportParser::ParseSection(std::vector<std::string>&& args, const std::string& filename,
|
||||
int line, std::string* err) {
|
||||
Result<Success> ImportParser::ParseSection(std::vector<std::string>&& args,
|
||||
const std::string& filename, int line) {
|
||||
if (args.size() != 2) {
|
||||
*err = "single argument needed for import\n";
|
||||
return false;
|
||||
return Error() << "single argument needed for import\n";
|
||||
}
|
||||
|
||||
std::string conf_file;
|
||||
bool ret = expand_props(args[1], &conf_file);
|
||||
if (!ret) {
|
||||
*err = "error while expanding import";
|
||||
return false;
|
||||
return Error() << "error while expanding import";
|
||||
}
|
||||
|
||||
LOG(INFO) << "Added '" << conf_file << "' to import list";
|
||||
if (filename_.empty()) filename_ = filename;
|
||||
imports_.emplace_back(std::move(conf_file), line);
|
||||
return true;
|
||||
return Success();
|
||||
}
|
||||
|
||||
void ImportParser::EndFile() {
|
||||
|
|
|
@ -28,8 +28,8 @@ namespace init {
|
|||
class ImportParser : public SectionParser {
|
||||
public:
|
||||
ImportParser(Parser* parser) : parser_(parser) {}
|
||||
bool ParseSection(std::vector<std::string>&& args, const std::string& filename, int line,
|
||||
std::string* err) override;
|
||||
Result<Success> ParseSection(std::vector<std::string>&& args, const std::string& filename,
|
||||
int line) override;
|
||||
void EndFile() override;
|
||||
|
||||
private:
|
||||
|
|
|
@ -22,6 +22,8 @@
|
|||
|
||||
#include <android-base/stringprintf.h>
|
||||
|
||||
#include "result.h"
|
||||
|
||||
namespace android {
|
||||
namespace init {
|
||||
|
||||
|
@ -34,20 +36,17 @@ class KeywordMap {
|
|||
virtual ~KeywordMap() {
|
||||
}
|
||||
|
||||
const Function FindFunction(const std::vector<std::string>& args, std::string* err) const {
|
||||
const Result<Function> FindFunction(const std::vector<std::string>& args) const {
|
||||
using android::base::StringPrintf;
|
||||
|
||||
if (args.empty()) {
|
||||
*err = "keyword needed, but not provided";
|
||||
return nullptr;
|
||||
}
|
||||
if (args.empty()) return Error() << "Keyword needed, but not provided";
|
||||
|
||||
auto& keyword = args[0];
|
||||
auto num_args = args.size() - 1;
|
||||
|
||||
auto function_info_it = map().find(keyword);
|
||||
if (function_info_it == map().end()) {
|
||||
*err = StringPrintf("invalid keyword '%s'", keyword.c_str());
|
||||
return nullptr;
|
||||
return Error() << StringPrintf("Invalid keyword '%s'", keyword.c_str());
|
||||
}
|
||||
|
||||
auto function_info = function_info_it->second;
|
||||
|
@ -55,22 +54,18 @@ class KeywordMap {
|
|||
auto min_args = std::get<0>(function_info);
|
||||
auto max_args = std::get<1>(function_info);
|
||||
if (min_args == max_args && num_args != min_args) {
|
||||
*err = StringPrintf("%s requires %zu argument%s",
|
||||
keyword.c_str(), min_args,
|
||||
(min_args > 1 || min_args == 0) ? "s" : "");
|
||||
return nullptr;
|
||||
return Error() << StringPrintf("%s requires %zu argument%s", keyword.c_str(), min_args,
|
||||
(min_args > 1 || min_args == 0) ? "s" : "");
|
||||
}
|
||||
|
||||
if (num_args < min_args || num_args > max_args) {
|
||||
if (max_args == std::numeric_limits<decltype(max_args)>::max()) {
|
||||
*err = StringPrintf("%s requires at least %zu argument%s",
|
||||
keyword.c_str(), min_args,
|
||||
min_args > 1 ? "s" : "");
|
||||
return Error() << StringPrintf("%s requires at least %zu argument%s",
|
||||
keyword.c_str(), min_args, min_args > 1 ? "s" : "");
|
||||
} else {
|
||||
*err = StringPrintf("%s requires between %zu and %zu arguments",
|
||||
keyword.c_str(), min_args, max_args);
|
||||
return Error() << StringPrintf("%s requires between %zu and %zu arguments",
|
||||
keyword.c_str(), min_args, max_args);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return std::get<Function>(function_info);
|
||||
|
|
|
@ -67,9 +67,8 @@ void Parser::ParseData(const std::string& filename, const std::string& data) {
|
|||
if (android::base::StartsWith(args[0], prefix.c_str())) {
|
||||
if (section_parser) section_parser->EndSection();
|
||||
|
||||
std::string ret_err;
|
||||
if (!callback(std::move(args), &ret_err)) {
|
||||
LOG(ERROR) << filename << ": " << state.line << ": " << ret_err;
|
||||
if (auto result = callback(std::move(args)); !result) {
|
||||
LOG(ERROR) << filename << ": " << state.line << ": " << result.error();
|
||||
}
|
||||
section_parser = nullptr;
|
||||
break;
|
||||
|
@ -78,16 +77,16 @@ void Parser::ParseData(const std::string& filename, const std::string& data) {
|
|||
if (section_parsers_.count(args[0])) {
|
||||
if (section_parser) section_parser->EndSection();
|
||||
section_parser = section_parsers_[args[0]].get();
|
||||
std::string ret_err;
|
||||
if (!section_parser->ParseSection(std::move(args), filename, state.line,
|
||||
&ret_err)) {
|
||||
LOG(ERROR) << filename << ": " << state.line << ": " << ret_err;
|
||||
if (auto result =
|
||||
section_parser->ParseSection(std::move(args), filename, state.line);
|
||||
!result) {
|
||||
LOG(ERROR) << filename << ": " << state.line << ": " << result.error();
|
||||
section_parser = nullptr;
|
||||
}
|
||||
} else if (section_parser) {
|
||||
std::string ret_err;
|
||||
if (!section_parser->ParseLineSection(std::move(args), state.line, &ret_err)) {
|
||||
LOG(ERROR) << filename << ": " << state.line << ": " << ret_err;
|
||||
if (auto result = section_parser->ParseLineSection(std::move(args), state.line);
|
||||
!result) {
|
||||
LOG(ERROR) << filename << ": " << state.line << ": " << result.error();
|
||||
}
|
||||
}
|
||||
args.clear();
|
||||
|
|
|
@ -22,6 +22,8 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "result.h"
|
||||
|
||||
// SectionParser is an interface that can parse a given 'section' in init.
|
||||
//
|
||||
// You can implement up to 4 functions below, with ParseSection() being mandatory.
|
||||
|
@ -51,9 +53,9 @@ namespace init {
|
|||
class SectionParser {
|
||||
public:
|
||||
virtual ~SectionParser() {}
|
||||
virtual bool ParseSection(std::vector<std::string>&& args, const std::string& filename,
|
||||
int line, std::string* err) = 0;
|
||||
virtual bool ParseLineSection(std::vector<std::string>&&, int, std::string*) { return true; };
|
||||
virtual Result<Success> ParseSection(std::vector<std::string>&& args,
|
||||
const std::string& filename, int line) = 0;
|
||||
virtual Result<Success> ParseLineSection(std::vector<std::string>&&, int) { return Success(); };
|
||||
virtual void EndSection(){};
|
||||
virtual void EndFile(){};
|
||||
};
|
||||
|
@ -67,7 +69,7 @@ class Parser {
|
|||
// Similar to ParseSection() and ParseLineSection(), this function returns bool with false
|
||||
// indicating a failure and has an std::string* err parameter into which an error string can
|
||||
// be written.
|
||||
using LineCallback = std::function<bool(std::vector<std::string>&&, std::string*)>;
|
||||
using LineCallback = std::function<Result<Success>(std::vector<std::string>&&)>;
|
||||
|
||||
Parser();
|
||||
|
||||
|
|
195
init/service.cpp
195
init/service.cpp
|
@ -333,12 +333,12 @@ void Service::DumpState() const {
|
|||
[] (const auto& info) { LOG(INFO) << *info; });
|
||||
}
|
||||
|
||||
bool Service::ParseCapabilities(const std::vector<std::string>& args, std::string* err) {
|
||||
Result<Success> Service::ParseCapabilities(const std::vector<std::string>& args) {
|
||||
capabilities_ = 0;
|
||||
|
||||
if (!CapAmbientSupported()) {
|
||||
*err = "capabilities requested but the kernel does not support ambient capabilities";
|
||||
return false;
|
||||
return Error()
|
||||
<< "capabilities requested but the kernel does not support ambient capabilities";
|
||||
}
|
||||
|
||||
unsigned int last_valid_cap = GetLastValidCap();
|
||||
|
@ -350,76 +350,71 @@ bool Service::ParseCapabilities(const std::vector<std::string>& args, std::strin
|
|||
const std::string& arg = args[i];
|
||||
int res = LookupCap(arg);
|
||||
if (res < 0) {
|
||||
*err = StringPrintf("invalid capability '%s'", arg.c_str());
|
||||
return false;
|
||||
return Error() << StringPrintf("invalid capability '%s'", arg.c_str());
|
||||
}
|
||||
unsigned int cap = static_cast<unsigned int>(res); // |res| is >= 0.
|
||||
if (cap > last_valid_cap) {
|
||||
*err = StringPrintf("capability '%s' not supported by the kernel", arg.c_str());
|
||||
return false;
|
||||
return Error() << StringPrintf("capability '%s' not supported by the kernel",
|
||||
arg.c_str());
|
||||
}
|
||||
capabilities_[cap] = true;
|
||||
}
|
||||
return true;
|
||||
return Success();
|
||||
}
|
||||
|
||||
bool Service::ParseClass(const std::vector<std::string>& args, std::string* err) {
|
||||
Result<Success> Service::ParseClass(const std::vector<std::string>& args) {
|
||||
classnames_ = std::set<std::string>(args.begin() + 1, args.end());
|
||||
return true;
|
||||
return Success();
|
||||
}
|
||||
|
||||
bool Service::ParseConsole(const std::vector<std::string>& args, std::string* err) {
|
||||
Result<Success> Service::ParseConsole(const std::vector<std::string>& args) {
|
||||
flags_ |= SVC_CONSOLE;
|
||||
console_ = args.size() > 1 ? "/dev/" + args[1] : "";
|
||||
return true;
|
||||
return Success();
|
||||
}
|
||||
|
||||
bool Service::ParseCritical(const std::vector<std::string>& args, std::string* err) {
|
||||
Result<Success> Service::ParseCritical(const std::vector<std::string>& args) {
|
||||
flags_ |= SVC_CRITICAL;
|
||||
return true;
|
||||
return Success();
|
||||
}
|
||||
|
||||
bool Service::ParseDisabled(const std::vector<std::string>& args, std::string* err) {
|
||||
Result<Success> Service::ParseDisabled(const std::vector<std::string>& args) {
|
||||
flags_ |= SVC_DISABLED;
|
||||
flags_ |= SVC_RC_DISABLED;
|
||||
return true;
|
||||
return Success();
|
||||
}
|
||||
|
||||
bool Service::ParseGroup(const std::vector<std::string>& args, std::string* err) {
|
||||
Result<Success> Service::ParseGroup(const std::vector<std::string>& args) {
|
||||
auto gid = DecodeUid(args[1]);
|
||||
if (!gid) {
|
||||
*err = "Unable to decode GID for '" + args[1] + "': " + gid.error();
|
||||
return false;
|
||||
return Error() << "Unable to decode GID for '" << args[1] << "': " << gid.error();
|
||||
}
|
||||
gid_ = *gid;
|
||||
|
||||
for (std::size_t n = 2; n < args.size(); n++) {
|
||||
gid = DecodeUid(args[n]);
|
||||
if (!gid) {
|
||||
*err = "Unable to decode GID for '" + args[n] + "': " + gid.error();
|
||||
return false;
|
||||
return Error() << "Unable to decode GID for '" << args[n] << "': " << gid.error();
|
||||
}
|
||||
supp_gids_.emplace_back(*gid);
|
||||
}
|
||||
return true;
|
||||
return Success();
|
||||
}
|
||||
|
||||
bool Service::ParsePriority(const std::vector<std::string>& args, std::string* err) {
|
||||
Result<Success> Service::ParsePriority(const std::vector<std::string>& args) {
|
||||
priority_ = 0;
|
||||
if (!ParseInt(args[1], &priority_,
|
||||
static_cast<int>(ANDROID_PRIORITY_HIGHEST), // highest is negative
|
||||
static_cast<int>(ANDROID_PRIORITY_LOWEST))) {
|
||||
*err = StringPrintf("process priority value must be range %d - %d",
|
||||
ANDROID_PRIORITY_HIGHEST, ANDROID_PRIORITY_LOWEST);
|
||||
return false;
|
||||
return Error() << StringPrintf("process priority value must be range %d - %d",
|
||||
ANDROID_PRIORITY_HIGHEST, ANDROID_PRIORITY_LOWEST);
|
||||
}
|
||||
return true;
|
||||
return Success();
|
||||
}
|
||||
|
||||
bool Service::ParseIoprio(const std::vector<std::string>& args, std::string* err) {
|
||||
Result<Success> Service::ParseIoprio(const std::vector<std::string>& args) {
|
||||
if (!ParseInt(args[2], &ioprio_pri_, 0, 7)) {
|
||||
*err = "priority value must be range 0 - 7";
|
||||
return false;
|
||||
return Error() << "priority value must be range 0 - 7";
|
||||
}
|
||||
|
||||
if (args[1] == "rt") {
|
||||
|
@ -429,14 +424,13 @@ bool Service::ParseIoprio(const std::vector<std::string>& args, std::string* err
|
|||
} else if (args[1] == "idle") {
|
||||
ioprio_class_ = IoSchedClass_IDLE;
|
||||
} else {
|
||||
*err = "ioprio option usage: ioprio <rt|be|idle> <0-7>";
|
||||
return false;
|
||||
return Error() << "ioprio option usage: ioprio <rt|be|idle> <0-7>";
|
||||
}
|
||||
|
||||
return true;
|
||||
return Success();
|
||||
}
|
||||
|
||||
bool Service::ParseKeycodes(const std::vector<std::string>& args, std::string* err) {
|
||||
Result<Success> Service::ParseKeycodes(const std::vector<std::string>& args) {
|
||||
for (std::size_t i = 1; i < args.size(); i++) {
|
||||
int code;
|
||||
if (ParseInt(args[i], &code)) {
|
||||
|
@ -445,22 +439,24 @@ bool Service::ParseKeycodes(const std::vector<std::string>& args, std::string* e
|
|||
LOG(WARNING) << "ignoring invalid keycode: " << args[i];
|
||||
}
|
||||
}
|
||||
return true;
|
||||
return Success();
|
||||
}
|
||||
|
||||
bool Service::ParseOneshot(const std::vector<std::string>& args, std::string* err) {
|
||||
Result<Success> Service::ParseOneshot(const std::vector<std::string>& args) {
|
||||
flags_ |= SVC_ONESHOT;
|
||||
return true;
|
||||
return Success();
|
||||
}
|
||||
|
||||
bool Service::ParseOnrestart(const std::vector<std::string>& args, std::string* err) {
|
||||
Result<Success> Service::ParseOnrestart(const std::vector<std::string>& args) {
|
||||
std::vector<std::string> str_args(args.begin() + 1, args.end());
|
||||
int line = onrestart_.NumCommands() + 1;
|
||||
onrestart_.AddCommand(str_args, line, err);
|
||||
return true;
|
||||
if (auto result = onrestart_.AddCommand(str_args, line); !result) {
|
||||
return Error() << "cannot add Onrestart command: " << result.error();
|
||||
}
|
||||
return Success();
|
||||
}
|
||||
|
||||
bool Service::ParseNamespace(const std::vector<std::string>& args, std::string* err) {
|
||||
Result<Success> Service::ParseNamespace(const std::vector<std::string>& args) {
|
||||
for (size_t i = 1; i < args.size(); i++) {
|
||||
if (args[i] == "pid") {
|
||||
namespace_flags_ |= CLONE_NEWPID;
|
||||
|
@ -469,65 +465,60 @@ bool Service::ParseNamespace(const std::vector<std::string>& args, std::string*
|
|||
} else if (args[i] == "mnt") {
|
||||
namespace_flags_ |= CLONE_NEWNS;
|
||||
} else {
|
||||
*err = "namespace must be 'pid' or 'mnt'";
|
||||
return false;
|
||||
return Error() << "namespace must be 'pid' or 'mnt'";
|
||||
}
|
||||
}
|
||||
return true;
|
||||
return Success();
|
||||
}
|
||||
|
||||
bool Service::ParseOomScoreAdjust(const std::vector<std::string>& args, std::string* err) {
|
||||
Result<Success> Service::ParseOomScoreAdjust(const std::vector<std::string>& args) {
|
||||
if (!ParseInt(args[1], &oom_score_adjust_, -1000, 1000)) {
|
||||
*err = "oom_score_adjust value must be in range -1000 - +1000";
|
||||
return false;
|
||||
return Error() << "oom_score_adjust value must be in range -1000 - +1000";
|
||||
}
|
||||
return true;
|
||||
return Success();
|
||||
}
|
||||
|
||||
bool Service::ParseMemcgSwappiness(const std::vector<std::string>& args, std::string* err) {
|
||||
Result<Success> Service::ParseMemcgSwappiness(const std::vector<std::string>& args) {
|
||||
if (!ParseInt(args[1], &swappiness_, 0)) {
|
||||
*err = "swappiness value must be equal or greater than 0";
|
||||
return false;
|
||||
return Error() << "swappiness value must be equal or greater than 0";
|
||||
}
|
||||
return true;
|
||||
return Success();
|
||||
}
|
||||
|
||||
bool Service::ParseMemcgLimitInBytes(const std::vector<std::string>& args, std::string* err) {
|
||||
Result<Success> Service::ParseMemcgLimitInBytes(const std::vector<std::string>& args) {
|
||||
if (!ParseInt(args[1], &limit_in_bytes_, 0)) {
|
||||
*err = "limit_in_bytes value must be equal or greater than 0";
|
||||
return false;
|
||||
return Error() << "limit_in_bytes value must be equal or greater than 0";
|
||||
}
|
||||
return true;
|
||||
return Success();
|
||||
}
|
||||
|
||||
bool Service::ParseMemcgSoftLimitInBytes(const std::vector<std::string>& args, std::string* err) {
|
||||
Result<Success> Service::ParseMemcgSoftLimitInBytes(const std::vector<std::string>& args) {
|
||||
if (!ParseInt(args[1], &soft_limit_in_bytes_, 0)) {
|
||||
*err = "soft_limit_in_bytes value must be equal or greater than 0";
|
||||
return false;
|
||||
return Error() << "soft_limit_in_bytes value must be equal or greater than 0";
|
||||
}
|
||||
return true;
|
||||
return Success();
|
||||
}
|
||||
|
||||
bool Service::ParseSeclabel(const std::vector<std::string>& args, std::string* err) {
|
||||
Result<Success> Service::ParseSeclabel(const std::vector<std::string>& args) {
|
||||
seclabel_ = args[1];
|
||||
return true;
|
||||
return Success();
|
||||
}
|
||||
|
||||
bool Service::ParseSetenv(const std::vector<std::string>& args, std::string* err) {
|
||||
Result<Success> Service::ParseSetenv(const std::vector<std::string>& args) {
|
||||
envvars_.emplace_back(args[1], args[2]);
|
||||
return true;
|
||||
return Success();
|
||||
}
|
||||
|
||||
bool Service::ParseShutdown(const std::vector<std::string>& args, std::string* err) {
|
||||
Result<Success> Service::ParseShutdown(const std::vector<std::string>& args) {
|
||||
if (args[1] == "critical") {
|
||||
flags_ |= SVC_SHUTDOWN_CRITICAL;
|
||||
return true;
|
||||
return Success();
|
||||
}
|
||||
return false;
|
||||
return Error() << "Invalid shutdown option";
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool Service::AddDescriptor(const std::vector<std::string>& args, std::string* err) {
|
||||
Result<Success> Service::AddDescriptor(const std::vector<std::string>& args) {
|
||||
int perm = args.size() > 3 ? std::strtoul(args[3].c_str(), 0, 8) : -1;
|
||||
Result<uid_t> uid = 0;
|
||||
Result<gid_t> gid = 0;
|
||||
|
@ -536,16 +527,14 @@ bool Service::AddDescriptor(const std::vector<std::string>& args, std::string* e
|
|||
if (args.size() > 4) {
|
||||
uid = DecodeUid(args[4]);
|
||||
if (!uid) {
|
||||
*err = "Unable to find UID for '" + args[4] + "': " + uid.error();
|
||||
return false;
|
||||
return Error() << "Unable to find UID for '" << args[4] << "': " << uid.error();
|
||||
}
|
||||
}
|
||||
|
||||
if (args.size() > 5) {
|
||||
gid = DecodeUid(args[5]);
|
||||
if (!gid) {
|
||||
*err = "Unable to find GID for '" + args[5] + "': " + gid.error();
|
||||
return false;
|
||||
return Error() << "Unable to find GID for '" << args[5] << "': " << gid.error();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -556,50 +545,45 @@ bool Service::AddDescriptor(const std::vector<std::string>& args, std::string* e
|
|||
[&descriptor] (const auto& other) { return descriptor.get() == other.get(); });
|
||||
|
||||
if (old != descriptors_.end()) {
|
||||
*err = "duplicate descriptor " + args[1] + " " + args[2];
|
||||
return false;
|
||||
return Error() << "duplicate descriptor " << args[1] << " " << args[2];
|
||||
}
|
||||
|
||||
descriptors_.emplace_back(std::move(descriptor));
|
||||
return true;
|
||||
return Success();
|
||||
}
|
||||
|
||||
// name type perm [ uid gid context ]
|
||||
bool Service::ParseSocket(const std::vector<std::string>& args, std::string* err) {
|
||||
Result<Success> Service::ParseSocket(const std::vector<std::string>& args) {
|
||||
if (!StartsWith(args[2], "dgram") && !StartsWith(args[2], "stream") &&
|
||||
!StartsWith(args[2], "seqpacket")) {
|
||||
*err = "socket type must be 'dgram', 'stream' or 'seqpacket'";
|
||||
return false;
|
||||
return Error() << "socket type must be 'dgram', 'stream' or 'seqpacket'";
|
||||
}
|
||||
return AddDescriptor<SocketInfo>(args, err);
|
||||
return AddDescriptor<SocketInfo>(args);
|
||||
}
|
||||
|
||||
// name type perm [ uid gid context ]
|
||||
bool Service::ParseFile(const std::vector<std::string>& args, std::string* err) {
|
||||
Result<Success> Service::ParseFile(const std::vector<std::string>& args) {
|
||||
if (args[2] != "r" && args[2] != "w" && args[2] != "rw") {
|
||||
*err = "file type must be 'r', 'w' or 'rw'";
|
||||
return false;
|
||||
return Error() << "file type must be 'r', 'w' or 'rw'";
|
||||
}
|
||||
if ((args[1][0] != '/') || (args[1].find("../") != std::string::npos)) {
|
||||
*err = "file name must not be relative";
|
||||
return false;
|
||||
return Error() << "file name must not be relative";
|
||||
}
|
||||
return AddDescriptor<FileInfo>(args, err);
|
||||
return AddDescriptor<FileInfo>(args);
|
||||
}
|
||||
|
||||
bool Service::ParseUser(const std::vector<std::string>& args, std::string* err) {
|
||||
Result<Success> Service::ParseUser(const std::vector<std::string>& args) {
|
||||
auto uid = DecodeUid(args[1]);
|
||||
if (!uid) {
|
||||
*err = "Unable to find UID for '" + args[1] + "': " + uid.error();
|
||||
return false;
|
||||
return Error() << "Unable to find UID for '" << args[1] << "': " << uid.error();
|
||||
}
|
||||
uid_ = *uid;
|
||||
return true;
|
||||
return Success();
|
||||
}
|
||||
|
||||
bool Service::ParseWritepid(const std::vector<std::string>& args, std::string* err) {
|
||||
Result<Success> Service::ParseWritepid(const std::vector<std::string>& args) {
|
||||
writepid_files_.assign(args.begin() + 1, args.end());
|
||||
return true;
|
||||
return Success();
|
||||
}
|
||||
|
||||
class Service::OptionParserMap : public KeywordMap<OptionParser> {
|
||||
|
@ -647,15 +631,13 @@ const Service::OptionParserMap::Map& Service::OptionParserMap::map() const {
|
|||
return option_parsers;
|
||||
}
|
||||
|
||||
bool Service::ParseLine(const std::vector<std::string>& args, std::string* err) {
|
||||
Result<Success> Service::ParseLine(const std::vector<std::string>& args) {
|
||||
static const OptionParserMap parser_map;
|
||||
auto parser = parser_map.FindFunction(args, err);
|
||||
auto parser = parser_map.FindFunction(args);
|
||||
|
||||
if (!parser) {
|
||||
return false;
|
||||
}
|
||||
if (!parser) return Error() << parser.error();
|
||||
|
||||
return (this->*parser)(args, err);
|
||||
return std::invoke(*parser, this, args);
|
||||
}
|
||||
|
||||
bool Service::ExecStart() {
|
||||
|
@ -1044,32 +1026,29 @@ void ServiceList::DumpState() const {
|
|||
}
|
||||
}
|
||||
|
||||
bool ServiceParser::ParseSection(std::vector<std::string>&& args, const std::string& filename,
|
||||
int line, std::string* err) {
|
||||
Result<Success> ServiceParser::ParseSection(std::vector<std::string>&& args,
|
||||
const std::string& filename, int line) {
|
||||
if (args.size() < 3) {
|
||||
*err = "services must have a name and a program";
|
||||
return false;
|
||||
return Error() << "services must have a name and a program";
|
||||
}
|
||||
|
||||
const std::string& name = args[1];
|
||||
if (!IsValidName(name)) {
|
||||
*err = StringPrintf("invalid service name '%s'", name.c_str());
|
||||
return false;
|
||||
return Error() << "invalid service name '" << name << "'";
|
||||
}
|
||||
|
||||
Service* old_service = service_list_->FindService(name);
|
||||
if (old_service) {
|
||||
*err = "ignored duplicate definition of service '" + name + "'";
|
||||
return false;
|
||||
return Error() << "ignored duplicate definition of service '" << name << "'";
|
||||
}
|
||||
|
||||
std::vector<std::string> str_args(args.begin() + 2, args.end());
|
||||
service_ = std::make_unique<Service>(name, str_args);
|
||||
return true;
|
||||
return Success();
|
||||
}
|
||||
|
||||
bool ServiceParser::ParseLineSection(std::vector<std::string>&& args, int line, std::string* err) {
|
||||
return service_ ? service_->ParseLine(std::move(args), err) : false;
|
||||
Result<Success> ServiceParser::ParseLineSection(std::vector<std::string>&& args, int line) {
|
||||
return service_ ? service_->ParseLine(std::move(args)) : Success();
|
||||
}
|
||||
|
||||
void ServiceParser::EndSection() {
|
||||
|
|
|
@ -76,7 +76,7 @@ class Service {
|
|||
static std::unique_ptr<Service> MakeTemporaryOneshotService(const std::vector<std::string>& args);
|
||||
|
||||
bool IsRunning() { return (flags_ & SVC_RUNNING) != 0; }
|
||||
bool ParseLine(const std::vector<std::string>& args, std::string* err);
|
||||
Result<Success> ParseLine(const std::vector<std::string>& args);
|
||||
bool ExecStart();
|
||||
bool Start();
|
||||
bool StartIfNotDisabled();
|
||||
|
@ -119,8 +119,7 @@ class Service {
|
|||
const std::vector<std::string>& args() const { return args_; }
|
||||
|
||||
private:
|
||||
using OptionParser = bool (Service::*) (const std::vector<std::string>& args,
|
||||
std::string* err);
|
||||
using OptionParser = Result<Success> (Service::*)(const std::vector<std::string>& args);
|
||||
class OptionParserMap;
|
||||
|
||||
void NotifyStateChange(const std::string& new_state) const;
|
||||
|
@ -130,32 +129,32 @@ class Service {
|
|||
void KillProcessGroup(int signal);
|
||||
void SetProcessAttributes();
|
||||
|
||||
bool ParseCapabilities(const std::vector<std::string>& args, std::string *err);
|
||||
bool ParseClass(const std::vector<std::string>& args, std::string* err);
|
||||
bool ParseConsole(const std::vector<std::string>& args, std::string* err);
|
||||
bool ParseCritical(const std::vector<std::string>& args, std::string* err);
|
||||
bool ParseDisabled(const std::vector<std::string>& args, std::string* err);
|
||||
bool ParseGroup(const std::vector<std::string>& args, std::string* err);
|
||||
bool ParsePriority(const std::vector<std::string>& args, std::string* err);
|
||||
bool ParseIoprio(const std::vector<std::string>& args, std::string* err);
|
||||
bool ParseKeycodes(const std::vector<std::string>& args, std::string* err);
|
||||
bool ParseOneshot(const std::vector<std::string>& args, std::string* err);
|
||||
bool ParseOnrestart(const std::vector<std::string>& args, std::string* err);
|
||||
bool ParseOomScoreAdjust(const std::vector<std::string>& args, std::string* err);
|
||||
bool ParseMemcgLimitInBytes(const std::vector<std::string>& args, std::string* err);
|
||||
bool ParseMemcgSoftLimitInBytes(const std::vector<std::string>& args, std::string* err);
|
||||
bool ParseMemcgSwappiness(const std::vector<std::string>& args, std::string* err);
|
||||
bool ParseNamespace(const std::vector<std::string>& args, std::string* err);
|
||||
bool ParseSeclabel(const std::vector<std::string>& args, std::string* err);
|
||||
bool ParseSetenv(const std::vector<std::string>& args, std::string* err);
|
||||
bool ParseShutdown(const std::vector<std::string>& args, std::string* err);
|
||||
bool ParseSocket(const std::vector<std::string>& args, std::string* err);
|
||||
bool ParseFile(const std::vector<std::string>& args, std::string* err);
|
||||
bool ParseUser(const std::vector<std::string>& args, std::string* err);
|
||||
bool ParseWritepid(const std::vector<std::string>& args, std::string* err);
|
||||
Result<Success> ParseCapabilities(const std::vector<std::string>& args);
|
||||
Result<Success> ParseClass(const std::vector<std::string>& args);
|
||||
Result<Success> ParseConsole(const std::vector<std::string>& args);
|
||||
Result<Success> ParseCritical(const std::vector<std::string>& args);
|
||||
Result<Success> ParseDisabled(const std::vector<std::string>& args);
|
||||
Result<Success> ParseGroup(const std::vector<std::string>& args);
|
||||
Result<Success> ParsePriority(const std::vector<std::string>& args);
|
||||
Result<Success> ParseIoprio(const std::vector<std::string>& args);
|
||||
Result<Success> ParseKeycodes(const std::vector<std::string>& args);
|
||||
Result<Success> ParseOneshot(const std::vector<std::string>& args);
|
||||
Result<Success> ParseOnrestart(const std::vector<std::string>& args);
|
||||
Result<Success> ParseOomScoreAdjust(const std::vector<std::string>& args);
|
||||
Result<Success> ParseMemcgLimitInBytes(const std::vector<std::string>& args);
|
||||
Result<Success> ParseMemcgSoftLimitInBytes(const std::vector<std::string>& args);
|
||||
Result<Success> ParseMemcgSwappiness(const std::vector<std::string>& args);
|
||||
Result<Success> ParseNamespace(const std::vector<std::string>& args);
|
||||
Result<Success> ParseSeclabel(const std::vector<std::string>& args);
|
||||
Result<Success> ParseSetenv(const std::vector<std::string>& args);
|
||||
Result<Success> ParseShutdown(const std::vector<std::string>& args);
|
||||
Result<Success> ParseSocket(const std::vector<std::string>& args);
|
||||
Result<Success> ParseFile(const std::vector<std::string>& args);
|
||||
Result<Success> ParseUser(const std::vector<std::string>& args);
|
||||
Result<Success> ParseWritepid(const std::vector<std::string>& args);
|
||||
|
||||
template <typename T>
|
||||
bool AddDescriptor(const std::vector<std::string>& args, std::string* err);
|
||||
Result<Success> AddDescriptor(const std::vector<std::string>& args);
|
||||
|
||||
static unsigned long next_start_order_;
|
||||
static bool is_exec_service_running_;
|
||||
|
@ -242,9 +241,9 @@ class ServiceList {
|
|||
class ServiceParser : public SectionParser {
|
||||
public:
|
||||
ServiceParser(ServiceList* service_list) : service_list_(service_list), service_(nullptr) {}
|
||||
bool ParseSection(std::vector<std::string>&& args, const std::string& filename, int line,
|
||||
std::string* err) override;
|
||||
bool ParseLineSection(std::vector<std::string>&& args, int line, std::string* err) override;
|
||||
Result<Success> ParseSection(std::vector<std::string>&& args, const std::string& filename,
|
||||
int line) override;
|
||||
Result<Success> ParseLineSection(std::vector<std::string>&& args, int line) override;
|
||||
void EndSection() override;
|
||||
|
||||
private:
|
||||
|
|
|
@ -223,10 +223,10 @@ DeviceHandler CreateDeviceHandler() {
|
|||
using namespace std::placeholders;
|
||||
std::vector<SysfsPermissions> sysfs_permissions;
|
||||
std::vector<Permissions> dev_permissions;
|
||||
parser.AddSingleLineParser(
|
||||
"/sys/", std::bind(ParsePermissionsLine, _1, _2, &sysfs_permissions, nullptr));
|
||||
parser.AddSingleLineParser("/sys/",
|
||||
std::bind(ParsePermissionsLine, _1, &sysfs_permissions, nullptr));
|
||||
parser.AddSingleLineParser("/dev/",
|
||||
std::bind(ParsePermissionsLine, _1, _2, nullptr, &dev_permissions));
|
||||
std::bind(ParsePermissionsLine, _1, nullptr, &dev_permissions));
|
||||
|
||||
parser.ParseConfig("/ueventd.rc");
|
||||
parser.ParseConfig("/vendor/ueventd.rc");
|
||||
|
|
|
@ -24,18 +24,16 @@
|
|||
namespace android {
|
||||
namespace init {
|
||||
|
||||
bool ParsePermissionsLine(std::vector<std::string>&& args, std::string* err,
|
||||
std::vector<SysfsPermissions>* out_sysfs_permissions,
|
||||
std::vector<Permissions>* out_dev_permissions) {
|
||||
Result<Success> ParsePermissionsLine(std::vector<std::string>&& args,
|
||||
std::vector<SysfsPermissions>* out_sysfs_permissions,
|
||||
std::vector<Permissions>* out_dev_permissions) {
|
||||
bool is_sysfs = out_sysfs_permissions != nullptr;
|
||||
if (is_sysfs && args.size() != 5) {
|
||||
*err = "/sys/ lines must have 5 entries";
|
||||
return false;
|
||||
return Error() << "/sys/ lines must have 5 entries";
|
||||
}
|
||||
|
||||
if (!is_sysfs && args.size() != 4) {
|
||||
*err = "/dev/ lines must have 4 entries";
|
||||
return false;
|
||||
return Error() << "/dev/ lines must have 4 entries";
|
||||
}
|
||||
|
||||
auto it = args.begin();
|
||||
|
@ -49,23 +47,20 @@ bool ParsePermissionsLine(std::vector<std::string>&& args, std::string* err,
|
|||
char* end_pointer = 0;
|
||||
mode_t perm = strtol(perm_string.c_str(), &end_pointer, 8);
|
||||
if (end_pointer == nullptr || *end_pointer != '\0') {
|
||||
*err = "invalid mode '" + perm_string + "'";
|
||||
return false;
|
||||
return Error() << "invalid mode '" << perm_string << "'";
|
||||
}
|
||||
|
||||
std::string& uid_string = *it++;
|
||||
passwd* pwd = getpwnam(uid_string.c_str());
|
||||
if (!pwd) {
|
||||
*err = "invalid uid '" + uid_string + "'";
|
||||
return false;
|
||||
return Error() << "invalid uid '" << uid_string << "'";
|
||||
}
|
||||
uid_t uid = pwd->pw_uid;
|
||||
|
||||
std::string& gid_string = *it++;
|
||||
struct group* grp = getgrnam(gid_string.c_str());
|
||||
if (!grp) {
|
||||
*err = "invalid gid '" + gid_string + "'";
|
||||
return false;
|
||||
return Error() << "invalid gid '" << gid_string << "'";
|
||||
}
|
||||
gid_t gid = grp->gr_gid;
|
||||
|
||||
|
@ -74,53 +69,49 @@ bool ParsePermissionsLine(std::vector<std::string>&& args, std::string* err,
|
|||
} else {
|
||||
out_dev_permissions->emplace_back(name, perm, uid, gid);
|
||||
}
|
||||
return true;
|
||||
return Success();
|
||||
}
|
||||
|
||||
bool SubsystemParser::ParseSection(std::vector<std::string>&& args, const std::string& filename,
|
||||
int line, std::string* err) {
|
||||
Result<Success> SubsystemParser::ParseSection(std::vector<std::string>&& args,
|
||||
const std::string& filename, int line) {
|
||||
if (args.size() != 2) {
|
||||
*err = "subsystems must have exactly one name";
|
||||
return false;
|
||||
return Error() << "subsystems must have exactly one name";
|
||||
}
|
||||
|
||||
if (std::find(subsystems_->begin(), subsystems_->end(), args[1]) != subsystems_->end()) {
|
||||
*err = "ignoring duplicate subsystem entry";
|
||||
return false;
|
||||
return Error() << "ignoring duplicate subsystem entry";
|
||||
}
|
||||
|
||||
subsystem_.name_ = args[1];
|
||||
|
||||
return true;
|
||||
return Success();
|
||||
}
|
||||
|
||||
bool SubsystemParser::ParseDevName(std::vector<std::string>&& args, std::string* err) {
|
||||
Result<Success> SubsystemParser::ParseDevName(std::vector<std::string>&& args) {
|
||||
if (args[1] == "uevent_devname") {
|
||||
subsystem_.devname_source_ = Subsystem::DevnameSource::DEVNAME_UEVENT_DEVNAME;
|
||||
return true;
|
||||
return Success();
|
||||
}
|
||||
if (args[1] == "uevent_devpath") {
|
||||
subsystem_.devname_source_ = Subsystem::DevnameSource::DEVNAME_UEVENT_DEVPATH;
|
||||
return true;
|
||||
return Success();
|
||||
}
|
||||
|
||||
*err = "invalid devname '" + args[1] + "'";
|
||||
return false;
|
||||
return Error() << "invalid devname '" << args[1] << "'";
|
||||
}
|
||||
|
||||
bool SubsystemParser::ParseDirName(std::vector<std::string>&& args, std::string* err) {
|
||||
Result<Success> SubsystemParser::ParseDirName(std::vector<std::string>&& args) {
|
||||
if (args[1].front() != '/') {
|
||||
*err = "dirname '" + args[1] + " ' does not start with '/'";
|
||||
return false;
|
||||
return Error() << "dirname '" << args[1] << " ' does not start with '/'";
|
||||
}
|
||||
|
||||
subsystem_.dir_name_ = args[1];
|
||||
return true;
|
||||
return Success();
|
||||
}
|
||||
|
||||
bool SubsystemParser::ParseLineSection(std::vector<std::string>&& args, int line, std::string* err) {
|
||||
using OptionParser =
|
||||
bool (SubsystemParser::*)(std::vector<std::string> && args, std::string * err);
|
||||
Result<Success> SubsystemParser::ParseLineSection(std::vector<std::string>&& args, int line) {
|
||||
using OptionParser = Result<Success> (SubsystemParser::*)(std::vector<std::string> && args);
|
||||
|
||||
static class OptionParserMap : public KeywordMap<OptionParser> {
|
||||
private:
|
||||
const Map& map() const override {
|
||||
|
@ -134,13 +125,11 @@ bool SubsystemParser::ParseLineSection(std::vector<std::string>&& args, int line
|
|||
}
|
||||
} parser_map;
|
||||
|
||||
auto parser = parser_map.FindFunction(args, err);
|
||||
auto parser = parser_map.FindFunction(args);
|
||||
|
||||
if (!parser) {
|
||||
return false;
|
||||
}
|
||||
if (!parser) return Error() << parser.error();
|
||||
|
||||
return (this->*parser)(std::move(args), err);
|
||||
return std::invoke(*parser, this, std::move(args));
|
||||
}
|
||||
|
||||
void SubsystemParser::EndSection() {
|
||||
|
|
|
@ -29,22 +29,22 @@ namespace init {
|
|||
class SubsystemParser : public SectionParser {
|
||||
public:
|
||||
SubsystemParser(std::vector<Subsystem>* subsystems) : subsystems_(subsystems) {}
|
||||
bool ParseSection(std::vector<std::string>&& args, const std::string& filename, int line,
|
||||
std::string* err) override;
|
||||
bool ParseLineSection(std::vector<std::string>&& args, int line, std::string* err) override;
|
||||
Result<Success> ParseSection(std::vector<std::string>&& args, const std::string& filename,
|
||||
int line) override;
|
||||
Result<Success> ParseLineSection(std::vector<std::string>&& args, int line) override;
|
||||
void EndSection() override;
|
||||
|
||||
private:
|
||||
bool ParseDevName(std::vector<std::string>&& args, std::string* err);
|
||||
bool ParseDirName(std::vector<std::string>&& args, std::string* err);
|
||||
Result<Success> ParseDevName(std::vector<std::string>&& args);
|
||||
Result<Success> ParseDirName(std::vector<std::string>&& args);
|
||||
|
||||
Subsystem subsystem_;
|
||||
std::vector<Subsystem>* subsystems_;
|
||||
};
|
||||
|
||||
bool ParsePermissionsLine(std::vector<std::string>&& args, std::string* err,
|
||||
std::vector<SysfsPermissions>* out_sysfs_permissions,
|
||||
std::vector<Permissions>* out_dev_permissions);
|
||||
Result<Success> ParsePermissionsLine(std::vector<std::string>&& args,
|
||||
std::vector<SysfsPermissions>* out_sysfs_permissions,
|
||||
std::vector<Permissions>* out_dev_permissions);
|
||||
|
||||
} // namespace init
|
||||
} // namespace android
|
||||
|
|
Loading…
Reference in a new issue