init: replace Result<Success> with Result<void>

Now that Result<T> is actually expected<T, ...>, and the expected
proposal states expected<void, ...> as the way to indicate an expected
object that returns either successfully with no object or an error,
let's move init's Result<Success> to the preferred Result<void>.

Bug: 132145659
Test: boot, init unit tests
Change-Id: Ib2f98396d8e6e274f95a496fcdfd8341f77585ee
This commit is contained in:
Tom Cherry 2019-06-10 11:08:01 -07:00
parent caa95d551d
commit bbcbc2ffb3
40 changed files with 457 additions and 514 deletions

View file

@ -28,9 +28,8 @@ using android::base::Join;
namespace android {
namespace init {
Result<Success> RunBuiltinFunction(const BuiltinFunction& function,
const std::vector<std::string>& args,
const std::string& context) {
Result<void> RunBuiltinFunction(const BuiltinFunction& function,
const std::vector<std::string>& args, const std::string& context) {
auto builtin_arguments = BuiltinArguments(context);
builtin_arguments.args.resize(args.size());
@ -51,7 +50,7 @@ Command::Command(BuiltinFunction f, bool execute_in_subcontext, std::vector<std:
args_(std::move(args)),
line_(line) {}
Result<Success> Command::InvokeFunc(Subcontext* subcontext) const {
Result<void> Command::InvokeFunc(Subcontext* subcontext) const {
if (subcontext) {
if (execute_in_subcontext_) {
return subcontext->Execute(args_);
@ -83,7 +82,7 @@ Action::Action(bool oneshot, Subcontext* subcontext, const std::string& filename
const KeywordFunctionMap* Action::function_map_ = nullptr;
Result<Success> Action::AddCommand(std::vector<std::string>&& args, int line) {
Result<void> Action::AddCommand(std::vector<std::string>&& args, int line) {
if (!function_map_) {
return Error() << "no function map available";
}
@ -92,7 +91,7 @@ Result<Success> Action::AddCommand(std::vector<std::string>&& args, int line) {
if (!function) return Error() << function.error();
commands_.emplace_back(function->second, function->first, std::move(args), line);
return Success();
return {};
}
void Action::AddCommand(BuiltinFunction f, std::vector<std::string>&& args, int line) {

View file

@ -31,15 +31,15 @@
namespace android {
namespace init {
Result<Success> RunBuiltinFunction(const BuiltinFunction& function,
const std::vector<std::string>& args, const std::string& context);
Result<void> RunBuiltinFunction(const BuiltinFunction& function,
const std::vector<std::string>& args, const std::string& context);
class Command {
public:
Command(BuiltinFunction f, bool execute_in_subcontext, std::vector<std::string>&& args,
int line);
Result<Success> InvokeFunc(Subcontext* subcontext) const;
Result<void> InvokeFunc(Subcontext* subcontext) const;
std::string BuildCommandString() const;
int line() const { return line_; }
@ -61,7 +61,7 @@ class Action {
const std::string& event_trigger,
const std::map<std::string, std::string>& property_triggers);
Result<Success> AddCommand(std::vector<std::string>&& args, int line);
Result<void> AddCommand(std::vector<std::string>&& args, int line);
void AddCommand(BuiltinFunction f, std::vector<std::string>&& args, int line);
std::size_t NumCommands() const;
void ExecuteOneCommand(std::size_t command) const;

View file

@ -55,8 +55,8 @@ bool IsActionableProperty(Subcontext* subcontext, const std::string& prop_name)
return CanReadProperty(subcontext->context(), prop_name);
}
Result<Success> ParsePropertyTrigger(const std::string& trigger, Subcontext* subcontext,
std::map<std::string, std::string>* property_triggers) {
Result<void> 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('=');
@ -74,12 +74,12 @@ Result<Success> ParsePropertyTrigger(const std::string& trigger, Subcontext* sub
if (auto [it, inserted] = property_triggers->emplace(prop_name, prop_value); !inserted) {
return Error() << "multiple property triggers found for same property";
}
return Success();
return {};
}
Result<Success> ParseTriggers(const std::vector<std::string>& args, Subcontext* subcontext,
std::string* event_trigger,
std::map<std::string, std::string>* property_triggers) {
Result<void> 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()) {
@ -108,13 +108,13 @@ Result<Success> ParseTriggers(const std::vector<std::string>& args, Subcontext*
}
}
return Success();
return {};
}
} // namespace
Result<Success> ActionParser::ParseSection(std::vector<std::string>&& args,
const std::string& filename, int line) {
Result<void> 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) {
return Error() << "Actions must have a trigger";
@ -142,19 +142,19 @@ Result<Success> ActionParser::ParseSection(std::vector<std::string>&& args,
property_triggers);
action_ = std::move(action);
return Success();
return {};
}
Result<Success> ActionParser::ParseLineSection(std::vector<std::string>&& args, int line) {
return action_ ? action_->AddCommand(std::move(args), line) : Success();
Result<void> ActionParser::ParseLineSection(std::vector<std::string>&& args, int line) {
return action_ ? action_->AddCommand(std::move(args), line) : Result<void>{};
}
Result<Success> ActionParser::EndSection() {
Result<void> ActionParser::EndSection() {
if (action_ && action_->NumCommands() > 0) {
action_manager_->AddAction(std::move(action_));
}
return Success();
return {};
}
} // namespace init

View file

@ -32,10 +32,10 @@ class ActionParser : public SectionParser {
public:
ActionParser(ActionManager* action_manager, std::vector<Subcontext>* subcontexts)
: action_manager_(action_manager), subcontexts_(subcontexts), action_(nullptr) {}
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;
Result<Success> EndSection() override;
Result<void> ParseSection(std::vector<std::string>&& args, const std::string& filename,
int line) override;
Result<void> ParseLineSection(std::vector<std::string>&& args, int line) override;
Result<void> EndSection() override;
private:
ActionManager* action_manager_;

View file

@ -165,20 +165,20 @@ static void bootchart_thread_main() {
LOG(INFO) << "Bootcharting finished";
}
static Result<Success> do_bootchart_start() {
static Result<void> do_bootchart_start() {
// We don't care about the content, but we do care that /data/bootchart/enabled actually exists.
std::string start;
if (!android::base::ReadFileToString("/data/bootchart/enabled", &start)) {
LOG(VERBOSE) << "Not bootcharting";
return Success();
return {};
}
g_bootcharting_thread = new std::thread(bootchart_thread_main);
return Success();
return {};
}
static Result<Success> do_bootchart_stop() {
if (!g_bootcharting_thread) return Success();
static Result<void> do_bootchart_stop() {
if (!g_bootcharting_thread) return {};
// Tell the worker thread it's time to quit.
{
@ -190,10 +190,10 @@ static Result<Success> do_bootchart_stop() {
g_bootcharting_thread->join();
delete g_bootcharting_thread;
g_bootcharting_thread = nullptr;
return Success();
return {};
}
Result<Success> do_bootchart(const BuiltinArguments& args) {
Result<void> do_bootchart(const BuiltinArguments& args) {
if (args[1] == "start") return do_bootchart_start();
return do_bootchart_stop();
}

View file

@ -26,7 +26,7 @@
namespace android {
namespace init {
Result<Success> do_bootchart(const BuiltinArguments& args);
Result<void> do_bootchart(const BuiltinArguments& args);
} // namespace init
} // namespace android

View file

@ -25,7 +25,7 @@
namespace android {
namespace init {
Result<Success> StartBoringSslSelfTest(const BuiltinArguments&) {
Result<void> StartBoringSslSelfTest(const BuiltinArguments&) {
pid_t id = fork();
if (id == 0) {
@ -49,7 +49,7 @@ Result<Success> StartBoringSslSelfTest(const BuiltinArguments&) {
PLOG(FATAL) << "Failed to fork for BoringSSL self test";
}
return Success();
return {};
}
} // namespace init

View file

@ -22,7 +22,7 @@
namespace android {
namespace init {
Result<Success> StartBoringSslSelfTest(const BuiltinArguments&);
Result<void> StartBoringSslSelfTest(const BuiltinArguments&);
} // namespace init
} // namespace android

View file

@ -90,14 +90,14 @@ namespace init {
static constexpr std::chrono::nanoseconds kCommandRetryTimeout = 5s;
static Result<Success> reboot_into_recovery(const std::vector<std::string>& options) {
static Result<void> reboot_into_recovery(const std::vector<std::string>& options) {
LOG(ERROR) << "Rebooting into recovery";
std::string err;
if (!write_bootloader_message(options, &err)) {
return Error() << "Failed to set bootloader message: " << err;
}
property_set("sys.powerctl", "reboot,recovery");
return Success();
return {};
}
template <typename F>
@ -107,10 +107,10 @@ static void ForEachServiceInClass(const std::string& classname, F function) {
}
}
static Result<Success> do_class_start(const BuiltinArguments& args) {
static Result<void> do_class_start(const BuiltinArguments& args) {
// Do not start a class if it has a property persist.dont_start_class.CLASS set to 1.
if (android::base::GetBoolProperty("persist.init.dont_start_class." + args[1], false))
return Success();
return {};
// Starting a class does not start services which are explicitly disabled.
// They must be started individually.
for (const auto& service : ServiceList::GetInstance()) {
@ -121,10 +121,10 @@ static Result<Success> do_class_start(const BuiltinArguments& args) {
}
}
}
return Success();
return {};
}
static Result<Success> do_class_start_post_data(const BuiltinArguments& args) {
static Result<void> do_class_start_post_data(const BuiltinArguments& args) {
if (args.context != kInitContext) {
return Error() << "command 'class_start_post_data' only available in init context";
}
@ -136,43 +136,43 @@ static Result<Success> do_class_start_post_data(const BuiltinArguments& args) {
}
}
}
return Success();
return {};
}
static Result<Success> do_class_stop(const BuiltinArguments& args) {
static Result<void> do_class_stop(const BuiltinArguments& args) {
ForEachServiceInClass(args[1], &Service::Stop);
return Success();
return {};
}
static Result<Success> do_class_reset(const BuiltinArguments& args) {
static Result<void> do_class_reset(const BuiltinArguments& args) {
ForEachServiceInClass(args[1], &Service::Reset);
return Success();
return {};
}
static Result<Success> do_class_reset_post_data(const BuiltinArguments& args) {
static Result<void> do_class_reset_post_data(const BuiltinArguments& args) {
if (args.context != kInitContext) {
return Error() << "command 'class_reset_post_data' only available in init context";
}
ForEachServiceInClass(args[1], &Service::ResetIfPostData);
return Success();
return {};
}
static Result<Success> do_class_restart(const BuiltinArguments& args) {
static Result<void> do_class_restart(const BuiltinArguments& args) {
// Do not restart a class if it has a property persist.dont_start_class.CLASS set to 1.
if (android::base::GetBoolProperty("persist.init.dont_start_class." + args[1], false))
return Success();
return {};
ForEachServiceInClass(args[1], &Service::Restart);
return Success();
return {};
}
static Result<Success> do_domainname(const BuiltinArguments& args) {
static Result<void> do_domainname(const BuiltinArguments& args) {
if (auto result = WriteFile("/proc/sys/kernel/domainname", args[1]); !result) {
return Error() << "Unable to write to /proc/sys/kernel/domainname: " << result.error();
}
return Success();
return {};
}
static Result<Success> do_enable(const BuiltinArguments& args) {
static Result<void> do_enable(const BuiltinArguments& args) {
Service* svc = ServiceList::GetInstance().FindService(args[1]);
if (!svc) return Error() << "Could not find service";
@ -180,10 +180,10 @@ static Result<Success> do_enable(const BuiltinArguments& args) {
return Error() << "Could not enable service: " << result.error();
}
return Success();
return {};
}
static Result<Success> do_exec(const BuiltinArguments& args) {
static Result<void> do_exec(const BuiltinArguments& args) {
auto service = Service::MakeTemporaryOneshotService(args.args);
if (!service) {
return Error() << "Could not create exec service";
@ -193,10 +193,10 @@ static Result<Success> do_exec(const BuiltinArguments& args) {
}
ServiceList::GetInstance().AddService(std::move(service));
return Success();
return {};
}
static Result<Success> do_exec_background(const BuiltinArguments& args) {
static Result<void> do_exec_background(const BuiltinArguments& args) {
auto service = Service::MakeTemporaryOneshotService(args.args);
if (!service) {
return Error() << "Could not create exec background service";
@ -206,10 +206,10 @@ static Result<Success> do_exec_background(const BuiltinArguments& args) {
}
ServiceList::GetInstance().AddService(std::move(service));
return Success();
return {};
}
static Result<Success> do_exec_start(const BuiltinArguments& args) {
static Result<void> do_exec_start(const BuiltinArguments& args) {
Service* service = ServiceList::GetInstance().FindService(args[1]);
if (!service) {
return Error() << "Service not found";
@ -219,24 +219,24 @@ static Result<Success> do_exec_start(const BuiltinArguments& args) {
return Error() << "Could not start exec service: " << result.error();
}
return Success();
return {};
}
static Result<Success> do_export(const BuiltinArguments& args) {
static Result<void> do_export(const BuiltinArguments& args) {
if (setenv(args[1].c_str(), args[2].c_str(), 1) == -1) {
return ErrnoError() << "setenv() failed";
}
return Success();
return {};
}
static Result<Success> do_hostname(const BuiltinArguments& args) {
static Result<void> do_hostname(const BuiltinArguments& args) {
if (auto result = WriteFile("/proc/sys/kernel/hostname", args[1]); !result) {
return Error() << "Unable to write to /proc/sys/kernel/hostname: " << result.error();
}
return Success();
return {};
}
static Result<Success> do_ifup(const BuiltinArguments& args) {
static Result<void> do_ifup(const BuiltinArguments& args) {
struct ifreq ifr;
strlcpy(ifr.ifr_name, args[1].c_str(), IFNAMSIZ);
@ -254,10 +254,10 @@ static Result<Success> do_ifup(const BuiltinArguments& args) {
return ErrnoError() << "ioctl(..., SIOCSIFFLAGS, ...) failed";
}
return Success();
return {};
}
static Result<Success> do_insmod(const BuiltinArguments& args) {
static Result<void> do_insmod(const BuiltinArguments& args) {
int flags = 0;
auto it = args.begin() + 1;
@ -275,34 +275,34 @@ static Result<Success> do_insmod(const BuiltinArguments& args) {
int rc = syscall(__NR_finit_module, fd.get(), options.c_str(), flags);
if (rc == -1) return ErrnoError() << "finit_module for \"" << filename << "\" failed";
return Success();
return {};
}
static Result<Success> do_interface_restart(const BuiltinArguments& args) {
static Result<void> do_interface_restart(const BuiltinArguments& args) {
Service* svc = ServiceList::GetInstance().FindInterface(args[1]);
if (!svc) return Error() << "interface " << args[1] << " not found";
svc->Restart();
return Success();
return {};
}
static Result<Success> do_interface_start(const BuiltinArguments& args) {
static Result<void> do_interface_start(const BuiltinArguments& args) {
Service* svc = ServiceList::GetInstance().FindInterface(args[1]);
if (!svc) return Error() << "interface " << args[1] << " not found";
if (auto result = svc->Start(); !result) {
return Error() << "Could not start interface: " << result.error();
}
return Success();
return {};
}
static Result<Success> do_interface_stop(const BuiltinArguments& args) {
static Result<void> do_interface_stop(const BuiltinArguments& args) {
Service* svc = ServiceList::GetInstance().FindInterface(args[1]);
if (!svc) return Error() << "interface " << args[1] << " not found";
svc->Stop();
return Success();
return {};
}
// mkdir <path> [mode] [owner] [group]
static Result<Success> do_mkdir(const BuiltinArguments& args) {
static Result<void> do_mkdir(const BuiltinArguments& args) {
mode_t mode = 0755;
if (args.size() >= 3) {
mode = std::strtoul(args[2].c_str(), 0, 8);
@ -351,15 +351,15 @@ static Result<Success> do_mkdir(const BuiltinArguments& args) {
{"--prompt_and_wipe_data", "--reason=set_policy_failed:"s + args[1]});
}
}
return Success();
return {};
}
/* umount <path> */
static Result<Success> do_umount(const BuiltinArguments& args) {
static Result<void> do_umount(const BuiltinArguments& args) {
if (umount(args[1].c_str()) < 0) {
return ErrnoError() << "umount() failed";
}
return Success();
return {};
}
static struct {
@ -387,7 +387,7 @@ static struct {
#define DATA_MNT_POINT "/data"
/* mount <type> <device> <path> <flags ...> <options> */
static Result<Success> do_mount(const BuiltinArguments& args) {
static Result<void> do_mount(const BuiltinArguments& args) {
const char* options = nullptr;
unsigned flags = 0;
bool wait = false;
@ -434,7 +434,7 @@ static Result<Success> do_mount(const BuiltinArguments& args) {
ioctl(loop, LOOP_CLR_FD, 0);
return ErrnoError() << "mount() failed";
}
return Success();
return {};
}
}
}
@ -449,7 +449,7 @@ static Result<Success> do_mount(const BuiltinArguments& args) {
}
return Success();
return {};
}
/* Imports .rc files from the specified paths. Default ones are applied if none is given.
@ -486,23 +486,23 @@ static void import_late(const std::vector<std::string>& args, size_t start_index
*
* return code is processed based on input code
*/
static Result<Success> queue_fs_event(int code) {
static Result<void> queue_fs_event(int code) {
if (code == FS_MGR_MNTALL_DEV_NEEDS_ENCRYPTION) {
ActionManager::GetInstance().QueueEventTrigger("encrypt");
return Success();
return {};
} else if (code == FS_MGR_MNTALL_DEV_MIGHT_BE_ENCRYPTED) {
property_set("ro.crypto.state", "encrypted");
property_set("ro.crypto.type", "block");
ActionManager::GetInstance().QueueEventTrigger("defaultcrypto");
return Success();
return {};
} else if (code == FS_MGR_MNTALL_DEV_NOT_ENCRYPTED) {
property_set("ro.crypto.state", "unencrypted");
ActionManager::GetInstance().QueueEventTrigger("nonencrypted");
return Success();
return {};
} else if (code == FS_MGR_MNTALL_DEV_NOT_ENCRYPTABLE) {
property_set("ro.crypto.state", "unsupported");
ActionManager::GetInstance().QueueEventTrigger("nonencrypted");
return Success();
return {};
} else if (code == FS_MGR_MNTALL_DEV_NEEDS_RECOVERY) {
/* Setup a wipe via recovery, and reboot into recovery */
if (android::gsi::IsGsiRunning()) {
@ -522,7 +522,7 @@ static Result<Success> queue_fs_event(int code) {
// Although encrypted, we have device key, so we do not need to
// do anything different from the nonencrypted case.
ActionManager::GetInstance().QueueEventTrigger("nonencrypted");
return Success();
return {};
} else if (code == FS_MGR_MNTALL_DEV_IS_METADATA_ENCRYPTED) {
if (fscrypt_install_keyring()) {
return Error() << "fscrypt_install_keyring() failed";
@ -533,7 +533,7 @@ static Result<Success> queue_fs_event(int code) {
// Although encrypted, vold has already set the device up, so we do not need to
// do anything different from the nonencrypted case.
ActionManager::GetInstance().QueueEventTrigger("nonencrypted");
return Success();
return {};
} else if (code == FS_MGR_MNTALL_DEV_NEEDS_METADATA_ENCRYPTION) {
if (fscrypt_install_keyring()) {
return Error() << "fscrypt_install_keyring() failed";
@ -544,7 +544,7 @@ static Result<Success> queue_fs_event(int code) {
// Although encrypted, vold has already set the device up, so we do not need to
// do anything different from the nonencrypted case.
ActionManager::GetInstance().QueueEventTrigger("nonencrypted");
return Success();
return {};
} else if (code > 0) {
Error() << "fs_mgr_mount_all() returned unexpected error " << code;
}
@ -558,7 +558,7 @@ static Result<Success> queue_fs_event(int code) {
* This function might request a reboot, in which case it will
* not return.
*/
static Result<Success> do_mount_all(const BuiltinArguments& args) {
static Result<void> do_mount_all(const BuiltinArguments& args) {
std::size_t na = 0;
bool import_rc = true;
bool queue_event = true;
@ -605,11 +605,11 @@ static Result<Success> do_mount_all(const BuiltinArguments& args) {
}
}
return Success();
return {};
}
/* umount_all <fstab> */
static Result<Success> do_umount_all(const BuiltinArguments& args) {
static Result<void> do_umount_all(const BuiltinArguments& args) {
Fstab fstab;
if (!ReadFstabFromFile(args[1], &fstab)) {
return Error() << "Could not read fstab";
@ -618,10 +618,10 @@ static Result<Success> do_umount_all(const BuiltinArguments& args) {
if (auto result = fs_mgr_umount_all(&fstab); result != 0) {
return Error() << "umount_fstab() failed " << result;
}
return Success();
return {};
}
static Result<Success> do_swapon_all(const BuiltinArguments& args) {
static Result<void> do_swapon_all(const BuiltinArguments& args) {
Fstab fstab;
if (!ReadFstabFromFile(args[1], &fstab)) {
return Error() << "Could not read fstab '" << args[1] << "'";
@ -631,50 +631,50 @@ static Result<Success> do_swapon_all(const BuiltinArguments& args) {
return Error() << "fs_mgr_swapon_all() failed";
}
return Success();
return {};
}
static Result<Success> do_setprop(const BuiltinArguments& args) {
static Result<void> do_setprop(const BuiltinArguments& args) {
property_set(args[1], args[2]);
return Success();
return {};
}
static Result<Success> do_setrlimit(const BuiltinArguments& args) {
static Result<void> do_setrlimit(const BuiltinArguments& args) {
auto rlimit = ParseRlimit(args.args);
if (!rlimit) return rlimit.error();
if (setrlimit(rlimit->first, &rlimit->second) == -1) {
return ErrnoError() << "setrlimit failed";
}
return Success();
return {};
}
static Result<Success> do_start(const BuiltinArguments& args) {
static Result<void> do_start(const BuiltinArguments& args) {
Service* svc = ServiceList::GetInstance().FindService(args[1]);
if (!svc) return Error() << "service " << args[1] << " not found";
if (auto result = svc->Start(); !result) {
return Error() << "Could not start service: " << result.error();
}
return Success();
return {};
}
static Result<Success> do_stop(const BuiltinArguments& args) {
static Result<void> do_stop(const BuiltinArguments& args) {
Service* svc = ServiceList::GetInstance().FindService(args[1]);
if (!svc) return Error() << "service " << args[1] << " not found";
svc->Stop();
return Success();
return {};
}
static Result<Success> do_restart(const BuiltinArguments& args) {
static Result<void> do_restart(const BuiltinArguments& args) {
Service* svc = ServiceList::GetInstance().FindService(args[1]);
if (!svc) return Error() << "service " << args[1] << " not found";
svc->Restart();
return Success();
return {};
}
static Result<Success> do_trigger(const BuiltinArguments& args) {
static Result<void> do_trigger(const BuiltinArguments& args) {
ActionManager::GetInstance().QueueEventTrigger(args[1]);
return Success();
return {};
}
static int MakeSymlink(const std::string& target, const std::string& linkpath) {
@ -695,33 +695,33 @@ static int MakeSymlink(const std::string& target, const std::string& linkpath) {
return rc;
}
static Result<Success> do_symlink(const BuiltinArguments& args) {
static Result<void> do_symlink(const BuiltinArguments& args) {
if (MakeSymlink(args[1], args[2]) < 0) {
// The symlink builtin is often used to create symlinks for older devices to be backwards
// compatible with new paths, therefore we skip reporting this error.
if (errno == EEXIST && android::base::GetMinimumLogSeverity() > android::base::DEBUG) {
return Success();
return {};
}
return ErrnoError() << "symlink() failed";
}
return Success();
return {};
}
static Result<Success> do_rm(const BuiltinArguments& args) {
static Result<void> do_rm(const BuiltinArguments& args) {
if (unlink(args[1].c_str()) < 0) {
return ErrnoError() << "unlink() failed";
}
return Success();
return {};
}
static Result<Success> do_rmdir(const BuiltinArguments& args) {
static Result<void> do_rmdir(const BuiltinArguments& args) {
if (rmdir(args[1].c_str()) < 0) {
return ErrnoError() << "rmdir() failed";
}
return Success();
return {};
}
static Result<Success> do_sysclktz(const BuiltinArguments& args) {
static Result<void> do_sysclktz(const BuiltinArguments& args) {
struct timezone tz = {};
if (!android::base::ParseInt(args[1], &tz.tz_minuteswest)) {
return Error() << "Unable to parse mins_west_of_gmt";
@ -730,10 +730,10 @@ static Result<Success> do_sysclktz(const BuiltinArguments& args) {
if (settimeofday(nullptr, &tz) == -1) {
return ErrnoError() << "settimeofday() failed";
}
return Success();
return {};
}
static Result<Success> do_verity_update_state(const BuiltinArguments& args) {
static Result<void> do_verity_update_state(const BuiltinArguments& args) {
int mode;
if (!fs_mgr_load_verity_state(&mode)) {
return Error() << "fs_mgr_load_verity_state() failed";
@ -755,18 +755,18 @@ static Result<Success> do_verity_update_state(const BuiltinArguments& args) {
property_set("partition." + partition + ".verified", std::to_string(mode));
}
return Success();
return {};
}
static Result<Success> do_write(const BuiltinArguments& args) {
static Result<void> do_write(const BuiltinArguments& args) {
if (auto result = WriteFile(args[1], args[2]); !result) {
return Error() << "Unable to write to file '" << args[1] << "': " << result.error();
}
return Success();
return {};
}
static Result<Success> readahead_file(const std::string& filename, bool fully) {
static Result<void> readahead_file(const std::string& filename, bool fully) {
android::base::unique_fd fd(TEMP_FAILURE_RETRY(open(filename.c_str(), O_RDONLY)));
if (fd == -1) {
return ErrnoError() << "Error opening file";
@ -786,10 +786,10 @@ static Result<Success> readahead_file(const std::string& filename, bool fully) {
return ErrnoError() << "Error reading file";
}
}
return Success();
return {};
}
static Result<Success> do_readahead(const BuiltinArguments& args) {
static Result<void> do_readahead(const BuiltinArguments& args) {
struct stat sb;
if (stat(args[1].c_str(), &sb)) {
@ -845,10 +845,10 @@ static Result<Success> do_readahead(const BuiltinArguments& args) {
} else if (pid < 0) {
return ErrnoError() << "Fork failed";
}
return Success();
return {};
}
static Result<Success> do_copy(const BuiltinArguments& args) {
static Result<void> do_copy(const BuiltinArguments& args) {
auto file_contents = ReadFile(args[1]);
if (!file_contents) {
return Error() << "Could not read input file '" << args[1] << "': " << file_contents.error();
@ -857,10 +857,10 @@ static Result<Success> do_copy(const BuiltinArguments& args) {
return Error() << "Could not write to output file '" << args[2] << "': " << result.error();
}
return Success();
return {};
}
static Result<Success> do_chown(const BuiltinArguments& args) {
static Result<void> do_chown(const BuiltinArguments& args) {
auto uid = DecodeUid(args[1]);
if (!uid) {
return Error() << "Unable to decode UID for '" << args[1] << "': " << uid.error();
@ -881,7 +881,7 @@ static Result<Success> do_chown(const BuiltinArguments& args) {
return ErrnoError() << "lchown() failed";
}
return Success();
return {};
}
static mode_t get_mode(const char *s) {
@ -897,15 +897,15 @@ static mode_t get_mode(const char *s) {
return mode;
}
static Result<Success> do_chmod(const BuiltinArguments& args) {
static Result<void> do_chmod(const BuiltinArguments& args) {
mode_t mode = get_mode(args[1].c_str());
if (fchmodat(AT_FDCWD, args[2].c_str(), mode, AT_SYMLINK_NOFOLLOW) < 0) {
return ErrnoError() << "fchmodat() failed";
}
return Success();
return {};
}
static Result<Success> do_restorecon(const BuiltinArguments& args) {
static Result<void> do_restorecon(const BuiltinArguments& args) {
int ret = 0;
struct flag_type {const char* name; int value;};
@ -944,16 +944,16 @@ static Result<Success> do_restorecon(const BuiltinArguments& args) {
}
if (ret) return ErrnoError() << "selinux_android_restorecon() failed";
return Success();
return {};
}
static Result<Success> do_restorecon_recursive(const BuiltinArguments& args) {
static Result<void> do_restorecon_recursive(const BuiltinArguments& args) {
std::vector<std::string> non_const_args(args.args);
non_const_args.insert(std::next(non_const_args.begin()), "--recursive");
return do_restorecon({std::move(non_const_args), args.context});
}
static Result<Success> do_loglevel(const BuiltinArguments& args) {
static Result<void> do_loglevel(const BuiltinArguments& args) {
// TODO: support names instead/as well?
int log_level = -1;
android::base::ParseInt(args[1], &log_level);
@ -971,20 +971,20 @@ static Result<Success> do_loglevel(const BuiltinArguments& args) {
return Error() << "invalid log level " << log_level;
}
android::base::SetMinimumLogSeverity(severity);
return Success();
return {};
}
static Result<Success> do_load_persist_props(const BuiltinArguments& args) {
static Result<void> do_load_persist_props(const BuiltinArguments& args) {
load_persist_props();
return Success();
return {};
}
static Result<Success> do_load_system_props(const BuiltinArguments& args) {
static Result<void> do_load_system_props(const BuiltinArguments& args) {
LOG(INFO) << "deprecated action `load_system_props` called.";
return Success();
return {};
}
static Result<Success> do_wait(const BuiltinArguments& args) {
static Result<void> do_wait(const BuiltinArguments& args) {
auto timeout = kCommandRetryTimeout;
if (args.size() == 3) {
int timeout_int;
@ -998,10 +998,10 @@ static Result<Success> do_wait(const BuiltinArguments& args) {
return Error() << "wait_for_file() failed";
}
return Success();
return {};
}
static Result<Success> do_wait_for_prop(const BuiltinArguments& args) {
static Result<void> do_wait_for_prop(const BuiltinArguments& args) {
const char* name = args[1].c_str();
const char* value = args[2].c_str();
size_t value_len = strlen(value);
@ -1015,15 +1015,15 @@ static Result<Success> do_wait_for_prop(const BuiltinArguments& args) {
if (!start_waiting_for_property(name, value)) {
return Error() << "already waiting for a property";
}
return Success();
return {};
}
static bool is_file_crypto() {
return android::base::GetProperty("ro.crypto.type", "") == "file";
}
static Result<Success> ExecWithRebootOnFailure(const std::string& reboot_reason,
const BuiltinArguments& args) {
static Result<void> ExecWithRebootOnFailure(const std::string& reboot_reason,
const BuiltinArguments& args) {
auto service = Service::MakeTemporaryOneshotService(args.args);
if (!service) {
return Error() << "Could not create exec service";
@ -1047,11 +1047,11 @@ static Result<Success> ExecWithRebootOnFailure(const std::string& reboot_reason,
return Error() << "Could not start exec service: " << result.error();
}
ServiceList::GetInstance().AddService(std::move(service));
return Success();
return {};
}
static Result<Success> do_installkey(const BuiltinArguments& args) {
if (!is_file_crypto()) return Success();
static Result<void> do_installkey(const BuiltinArguments& args) {
if (!is_file_crypto()) return {};
auto unencrypted_dir = args[1] + fscrypt_unencrypted_folder;
if (!make_dir(unencrypted_dir, 0700) && errno != EEXIST) {
@ -1062,19 +1062,19 @@ static Result<Success> do_installkey(const BuiltinArguments& args) {
{{"exec", "/system/bin/vdc", "--wait", "cryptfs", "enablefilecrypto"}, args.context});
}
static Result<Success> do_init_user0(const BuiltinArguments& args) {
static Result<void> do_init_user0(const BuiltinArguments& args) {
return ExecWithRebootOnFailure(
"init_user0_failed",
{{"exec", "/system/bin/vdc", "--wait", "cryptfs", "init_user0"}, args.context});
}
static Result<Success> do_mark_post_data(const BuiltinArguments& args) {
static Result<void> do_mark_post_data(const BuiltinArguments& args) {
ServiceList::GetInstance().MarkPostData();
return Success();
return {};
}
static Result<Success> do_parse_apex_configs(const BuiltinArguments& args) {
static Result<void> do_parse_apex_configs(const BuiltinArguments& args) {
glob_t glob_result;
// @ is added to filter out the later paths, which are bind mounts of the places
// where the APEXes are really mounted at. Otherwise, we will parse the
@ -1102,15 +1102,15 @@ static Result<Success> do_parse_apex_configs(const BuiltinArguments& args) {
}
ServiceList::GetInstance().MarkServicesUpdate();
if (success) {
return Success();
return {};
} else {
return Error() << "Could not parse apex configs";
}
}
static Result<Success> do_enter_default_mount_ns(const BuiltinArguments& args) {
static Result<void> do_enter_default_mount_ns(const BuiltinArguments& args) {
if (SwitchToDefaultMountNamespace()) {
return Success();
return {};
} else {
return Error() << "Failed to enter into default mount namespace";
}

View file

@ -29,7 +29,7 @@
namespace android {
namespace init {
using BuiltinFunction = std::function<Result<Success>(const BuiltinArguments&)>;
using BuiltinFunction = std::function<Result<void>(const BuiltinArguments&)>;
using KeywordFunctionMap = KeywordMap<std::pair<bool, BuiltinFunction>>;
class BuiltinFunctionMap : public KeywordFunctionMap {

View file

@ -28,17 +28,17 @@ namespace init {
Epoll::Epoll() {}
Result<Success> Epoll::Open() {
if (epoll_fd_ >= 0) return Success();
Result<void> Epoll::Open() {
if (epoll_fd_ >= 0) return {};
epoll_fd_.reset(epoll_create1(EPOLL_CLOEXEC));
if (epoll_fd_ == -1) {
return ErrnoError() << "epoll_create1 failed";
}
return Success();
return {};
}
Result<Success> Epoll::RegisterHandler(int fd, std::function<void()> handler, uint32_t events) {
Result<void> Epoll::RegisterHandler(int fd, std::function<void()> handler, uint32_t events) {
if (!events) {
return Error() << "Must specify events";
}
@ -52,24 +52,24 @@ Result<Success> Epoll::RegisterHandler(int fd, std::function<void()> handler, ui
// pointer to the std::function in the map directly for epoll_ctl.
ev.data.ptr = reinterpret_cast<void*>(&it->second);
if (epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, fd, &ev) == -1) {
Result<Success> result = ErrnoError() << "epoll_ctl failed to add fd";
Result<void> result = ErrnoError() << "epoll_ctl failed to add fd";
epoll_handlers_.erase(fd);
return result;
}
return Success();
return {};
}
Result<Success> Epoll::UnregisterHandler(int fd) {
Result<void> Epoll::UnregisterHandler(int fd) {
if (epoll_ctl(epoll_fd_, EPOLL_CTL_DEL, fd, nullptr) == -1) {
return ErrnoError() << "epoll_ctl failed to remove fd";
}
if (epoll_handlers_.erase(fd) != 1) {
return Error() << "Attempting to remove epoll handler for FD without an existing handler";
}
return Success();
return {};
}
Result<Success> Epoll::Wait(std::optional<std::chrono::milliseconds> timeout) {
Result<void> Epoll::Wait(std::optional<std::chrono::milliseconds> timeout) {
int timeout_ms = -1;
if (timeout && timeout->count() < INT_MAX) {
timeout_ms = timeout->count();
@ -81,7 +81,7 @@ Result<Success> Epoll::Wait(std::optional<std::chrono::milliseconds> timeout) {
} else if (nr == 1) {
std::invoke(*reinterpret_cast<std::function<void()>*>(ev.data.ptr));
}
return Success();
return {};
}
} // namespace init

View file

@ -36,11 +36,10 @@ class Epoll {
public:
Epoll();
Result<Success> Open();
Result<Success> RegisterHandler(int fd, std::function<void()> handler,
uint32_t events = EPOLLIN);
Result<Success> UnregisterHandler(int fd);
Result<Success> Wait(std::optional<std::chrono::milliseconds> timeout);
Result<void> Open();
Result<void> RegisterHandler(int fd, std::function<void()> handler, uint32_t events = EPOLLIN);
Result<void> UnregisterHandler(int fd);
Result<void> Wait(std::optional<std::chrono::milliseconds> timeout);
private:
android::base::unique_fd epoll_fd_;

View file

@ -23,16 +23,16 @@ using android::base::StartsWith;
namespace android {
namespace init {
Result<Success> HostImportParser::ParseSection(std::vector<std::string>&& args, const std::string&,
int) {
Result<void> HostImportParser::ParseSection(std::vector<std::string>&& args, const std::string&,
int) {
if (args.size() != 2) {
return Error() << "single argument needed for import\n";
}
return Success();
return {};
}
Result<Success> HostImportParser::ParseLineSection(std::vector<std::string>&&, int) {
Result<void> HostImportParser::ParseLineSection(std::vector<std::string>&&, int) {
return Error() << "Unexpected line found after import statement";
}

View file

@ -27,8 +27,8 @@ namespace init {
class HostImportParser : public SectionParser {
public:
HostImportParser() {}
Result<Success> ParseSection(std::vector<std::string>&& args, const std::string&, int) override;
Result<Success> ParseLineSection(std::vector<std::string>&&, int) override;
Result<void> ParseSection(std::vector<std::string>&& args, const std::string&, int) override;
Result<void> ParseLineSection(std::vector<std::string>&&, int) override;
};
} // namespace init

View file

@ -118,8 +118,8 @@ passwd* getpwnam(const char* login) { // NOLINT: implementing bad function.
namespace android {
namespace init {
static Result<Success> do_stub(const BuiltinArguments& args) {
return Success();
static Result<void> do_stub(const BuiltinArguments& args) {
return {};
}
#include "generated_stub_builtin_function_map.h"

View file

@ -23,8 +23,8 @@
namespace android {
namespace init {
Result<Success> ImportParser::ParseSection(std::vector<std::string>&& args,
const std::string& filename, int line) {
Result<void> ImportParser::ParseSection(std::vector<std::string>&& args,
const std::string& filename, int line) {
if (args.size() != 2) {
return Error() << "single argument needed for import\n";
}
@ -38,10 +38,10 @@ Result<Success> ImportParser::ParseSection(std::vector<std::string>&& args,
LOG(INFO) << "Added '" << conf_file << "' to import list";
if (filename_.empty()) filename_ = filename;
imports_.emplace_back(std::move(conf_file), line);
return Success();
return {};
}
Result<Success> ImportParser::ParseLineSection(std::vector<std::string>&&, int) {
Result<void> ImportParser::ParseLineSection(std::vector<std::string>&&, int) {
return Error() << "Unexpected line found after import statement";
}

View file

@ -28,9 +28,9 @@ namespace init {
class ImportParser : public SectionParser {
public:
ImportParser(Parser* parser) : parser_(parser) {}
Result<Success> ParseSection(std::vector<std::string>&& args, const std::string& filename,
int line) override;
Result<Success> ParseLineSection(std::vector<std::string>&&, int) override;
Result<void> ParseSection(std::vector<std::string>&& args, const std::string& filename,
int line) override;
Result<void> ParseLineSection(std::vector<std::string>&&, int) override;
void EndFile() override;
private:

View file

@ -237,18 +237,18 @@ static std::optional<boot_clock::time_point> HandleProcessActions() {
return next_process_action_time;
}
static Result<Success> DoControlStart(Service* service) {
static Result<void> DoControlStart(Service* service) {
return service->Start();
}
static Result<Success> DoControlStop(Service* service) {
static Result<void> DoControlStop(Service* service) {
service->Stop();
return Success();
return {};
}
static Result<Success> DoControlRestart(Service* service) {
static Result<void> DoControlRestart(Service* service) {
service->Restart();
return Success();
return {};
}
enum class ControlTarget {
@ -258,16 +258,16 @@ enum class ControlTarget {
struct ControlMessageFunction {
ControlTarget target;
std::function<Result<Success>(Service*)> action;
std::function<Result<void>(Service*)> action;
};
static const std::map<std::string, ControlMessageFunction>& get_control_message_map() {
// clang-format off
static const std::map<std::string, ControlMessageFunction> control_message_functions = {
{"sigstop_on", {ControlTarget::SERVICE,
[](auto* service) { service->set_sigstop(true); return Success(); }}},
[](auto* service) { service->set_sigstop(true); return Result<void>{}; }}},
{"sigstop_off", {ControlTarget::SERVICE,
[](auto* service) { service->set_sigstop(false); return Success(); }}},
[](auto* service) { service->set_sigstop(false); return Result<void>{}; }}},
{"start", {ControlTarget::SERVICE, DoControlStart}},
{"stop", {ControlTarget::SERVICE, DoControlStop}},
{"restart", {ControlTarget::SERVICE, DoControlRestart}},
@ -330,7 +330,7 @@ bool HandleControlMessage(const std::string& msg, const std::string& name, pid_t
return true;
}
static Result<Success> wait_for_coldboot_done_action(const BuiltinArguments& args) {
static Result<void> wait_for_coldboot_done_action(const BuiltinArguments& args) {
Timer t;
LOG(VERBOSE) << "Waiting for " COLDBOOT_DONE "...";
@ -348,18 +348,18 @@ static Result<Success> wait_for_coldboot_done_action(const BuiltinArguments& arg
}
property_set("ro.boottime.init.cold_boot_wait", std::to_string(t.duration().count()));
return Success();
return {};
}
static Result<Success> console_init_action(const BuiltinArguments& args) {
static Result<void> console_init_action(const BuiltinArguments& args) {
std::string console = GetProperty("ro.boot.console", "");
if (!console.empty()) {
default_console = "/dev/" + console;
}
return Success();
return {};
}
static Result<Success> SetupCgroupsAction(const BuiltinArguments&) {
static Result<void> SetupCgroupsAction(const BuiltinArguments&) {
// Have to create <CGROUPS_RC_DIR> using make_dir function
// for appropriate sepolicy to be set for it
make_dir(android::base::Dirname(CGROUPS_RC_PATH), 0711);
@ -367,7 +367,7 @@ static Result<Success> SetupCgroupsAction(const BuiltinArguments&) {
return ErrnoError() << "Failed to setup cgroups";
}
return Success();
return {};
}
static void import_kernel_nv(const std::string& key, const std::string& value, bool for_emulator) {
@ -451,19 +451,19 @@ static void process_kernel_cmdline() {
if (qemu[0]) import_kernel_cmdline(true, import_kernel_nv);
}
static Result<Success> property_enable_triggers_action(const BuiltinArguments& args) {
static Result<void> property_enable_triggers_action(const BuiltinArguments& args) {
/* Enable property triggers. */
property_triggers_enabled = 1;
return Success();
return {};
}
static Result<Success> queue_property_triggers_action(const BuiltinArguments& args) {
static Result<void> queue_property_triggers_action(const BuiltinArguments& args) {
ActionManager::GetInstance().QueueBuiltinAction(property_enable_triggers_action, "enable_property_trigger");
ActionManager::GetInstance().QueueAllPropertyActions();
return Success();
return {};
}
static Result<Success> InitBinder(const BuiltinArguments& args) {
static Result<void> InitBinder(const BuiltinArguments& args) {
// init's use of binder is very limited. init cannot:
// - have any binder threads
// - receive incoming binder calls
@ -478,7 +478,7 @@ static Result<Success> InitBinder(const BuiltinArguments& args) {
android::ProcessState::self()->setCallRestriction(
ProcessState::CallRestriction::ERROR_IF_NOT_ONEWAY);
#endif
return Success();
return {};
}
// Set the UDC controller for the ConfigFS USB Gadgets.
@ -757,14 +757,14 @@ int SecondStageMain(int argc, char** argv) {
am.QueueBuiltinAction(SetKptrRestrictAction, "SetKptrRestrict");
Keychords keychords;
am.QueueBuiltinAction(
[&epoll, &keychords](const BuiltinArguments& args) -> Result<Success> {
for (const auto& svc : ServiceList::GetInstance()) {
keychords.Register(svc->keycodes());
}
keychords.Start(&epoll, HandleKeychord);
return Success();
},
"KeychordInit");
[&epoll, &keychords](const BuiltinArguments& args) -> Result<void> {
for (const auto& svc : ServiceList::GetInstance()) {
keychords.Register(svc->keycodes());
}
keychords.Start(&epoll, HandleKeychord);
return {};
},
"KeychordInit");
am.QueueBuiltinAction(console_init_action, "console_init");
// Trigger all the boot actions to get us started.

View file

@ -180,7 +180,7 @@ TEST(init, EventTriggerOrderMultipleFiles) {
auto execute_command = [&num_executed](const BuiltinArguments& args) {
EXPECT_EQ(2U, args.size());
EXPECT_EQ(++num_executed, std::stoi(args[1]));
return Success();
return Result<void>{};
};
TestFunctionMap test_function_map;

View file

@ -33,7 +33,7 @@
namespace android {
namespace init {
Result<Success> ModaliasHandler::ParseDepCallback(std::vector<std::string>&& args) {
Result<void> ModaliasHandler::ParseDepCallback(std::vector<std::string>&& args) {
std::vector<std::string> deps;
// Set first item as our modules path
@ -58,10 +58,10 @@ Result<Success> ModaliasHandler::ParseDepCallback(std::vector<std::string>&& arg
std::replace(mod_name.begin(), mod_name.end(), '-', '_');
this->module_deps_[mod_name] = deps;
return Success();
return {};
}
Result<Success> ModaliasHandler::ParseAliasCallback(std::vector<std::string>&& args) {
Result<void> ModaliasHandler::ParseAliasCallback(std::vector<std::string>&& args) {
auto it = args.begin();
const std::string& type = *it++;
@ -77,7 +77,7 @@ Result<Success> ModaliasHandler::ParseAliasCallback(std::vector<std::string>&& a
std::string& module_name = *it++;
this->module_aliases_.emplace_back(alias, module_name);
return Success();
return {};
}
ModaliasHandler::ModaliasHandler() {
@ -100,7 +100,7 @@ ModaliasHandler::ModaliasHandler() {
for (const auto& base_path : base_paths) dep_parser.ParseConfig(base_path + "modules.dep");
}
Result<Success> ModaliasHandler::Insmod(const std::string& path_name, const std::string& args) {
Result<void> ModaliasHandler::Insmod(const std::string& path_name, const std::string& args) {
base::unique_fd fd(
TEMP_FAILURE_RETRY(open(path_name.c_str(), O_RDONLY | O_NOFOLLOW | O_CLOEXEC)));
if (fd == -1) return ErrnoError() << "Could not open module '" << path_name << "'";
@ -109,17 +109,17 @@ Result<Success> ModaliasHandler::Insmod(const std::string& path_name, const std:
if (ret != 0) {
if (errno == EEXIST) {
// Module already loaded
return Success();
return {};
}
return ErrnoError() << "Failed to insmod '" << path_name << "' with args '" << args << "'";
}
LOG(INFO) << "Loaded kernel module " << path_name;
return Success();
return {};
}
Result<Success> ModaliasHandler::InsmodWithDeps(const std::string& module_name,
const std::string& args) {
Result<void> ModaliasHandler::InsmodWithDeps(const std::string& module_name,
const std::string& args) {
if (module_name.empty()) {
return Error() << "Need valid module name";
}

View file

@ -35,11 +35,11 @@ class ModaliasHandler : public UeventHandler {
void HandleUevent(const Uevent& uevent) override;
private:
Result<Success> InsmodWithDeps(const std::string& module_name, const std::string& args);
Result<Success> Insmod(const std::string& path_name, const std::string& args);
Result<void> InsmodWithDeps(const std::string& module_name, const std::string& args);
Result<void> Insmod(const std::string& path_name, const std::string& args);
Result<Success> ParseDepCallback(std::vector<std::string>&& args);
Result<Success> ParseAliasCallback(std::vector<std::string>&& args);
Result<void> ParseDepCallback(std::vector<std::string>&& args);
Result<void> ParseAliasCallback(std::vector<std::string>&& args);
std::vector<std::pair<std::string, std::string>> module_aliases_;
std::unordered_map<std::string, std::vector<std::string>> module_deps_;

View file

@ -27,7 +27,7 @@
// SectionParser is an interface that can parse a given 'section' in init.
//
// You can implement up to 4 functions below, with ParseSection being mandatory. The first two
// functions return Result<Success> indicating if they have an error. It will be reported along
// functions return Result<void> indicating if they have an error. It will be reported along
// with the filename and line number of where the error occurred.
//
// 1) ParseSection
@ -51,10 +51,10 @@ namespace init {
class SectionParser {
public:
virtual ~SectionParser() {}
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 Result<Success> EndSection() { return Success(); };
virtual Result<void> ParseSection(std::vector<std::string>&& args, const std::string& filename,
int line) = 0;
virtual Result<void> ParseLineSection(std::vector<std::string>&&, int) { return {}; };
virtual Result<void> EndSection() { return {}; };
virtual void EndFile(){};
};
@ -67,7 +67,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<Result<Success>(std::vector<std::string>&&)>;
using LineCallback = std::function<Result<void>(std::vector<std::string>&&)>;
Parser();

View file

@ -169,7 +169,7 @@ Result<PersistentProperties> LoadPersistentPropertyFile() {
return Error() << "Unable to parse persistent property file: Could not parse protobuf";
}
Result<Success> WritePersistentPropertyFile(const PersistentProperties& persistent_properties) {
Result<void> WritePersistentPropertyFile(const PersistentProperties& persistent_properties) {
const std::string temp_filename = persistent_property_filename + ".tmp";
unique_fd fd(TEMP_FAILURE_RETRY(
open(temp_filename.c_str(), O_WRONLY | O_CREAT | O_NOFOLLOW | O_TRUNC | O_CLOEXEC, 0600)));
@ -191,7 +191,7 @@ Result<Success> WritePersistentPropertyFile(const PersistentProperties& persiste
unlink(temp_filename.c_str());
return Error(saved_errno) << "Unable to rename persistent property file";
}
return Success();
return {};
}
// Persistent properties are not written often, so we rather not keep any data in memory and read

View file

@ -30,7 +30,7 @@ void WritePersistentProperty(const std::string& name, const std::string& value);
// Exposed only for testing
Result<PersistentProperties> LoadPersistentPropertyFile();
Result<Success> WritePersistentPropertyFile(const PersistentProperties& persistent_properties);
Result<void> WritePersistentPropertyFile(const PersistentProperties& persistent_properties);
extern std::string persistent_property_filename;
} // namespace init

View file

@ -707,7 +707,7 @@ bool HandlePowerctlMessage(const std::string& command) {
// Queue built-in shutdown_done
auto shutdown_handler = [cmd, command, reboot_target, run_fsck](const BuiltinArguments&) {
DoReboot(cmd, command, reboot_target, run_fsck);
return Success();
return Result<void>{};
};
ActionManager::GetInstance().QueueBuiltinAction(shutdown_handler, "shutdown_done");

View file

@ -14,66 +14,14 @@
* limitations under the License.
*/
// This file contains classes for returning a successful result along with an optional
// arbitrarily typed return value or for returning a failure result along with an optional string
// indicating why the function failed.
// There are 3 classes that implement this functionality and one additional helper type.
//
// Result<T> either contains a member of type T that can be accessed using similar semantics as
// std::optional<T> or it contains a ResultError describing an error, which can be accessed via
// Result<T>::error().
//
// ResultError is a type that contains both a std::string describing the error and a copy of errno
// from when the error occurred. ResultError can be used in an ostream directly to print its
// string value.
//
// Success is a typedef that aids in creating Result<T> that do not contain a return value.
// Result<Nothing> is the correct return type for a function that either returns successfully or
// returns an error value. Returning Nothing() from a function that returns Result<Nothing> is the
// correct way to indicate that a function without a return type has completed successfully.
//
// A successful Result<T> is constructed implicitly from any type that can be implicitly converted
// to T or from the constructor arguments for T. This allows you to return a type T directly from
// a function that returns Result<T>.
//
// Error and ErrnoError are used to construct a Result<T> that has failed. The Error class takes
// an ostream as an input and are implicitly cast to a Result<T> containing that failure.
// ErrnoError() is a helper function to create an Error class that appends ": " + strerror(errno)
// to the end of the failure string to aid in interacting with C APIs. Alternatively, an errno
// value can be directly specified via the Error() constructor.
//
// ResultError can be used in the ostream when using Error to construct a Result<T>. In this case,
// the string that the ResultError takes is passed through the stream normally, but the errno is
// passed to the Result<T>. This can be used to pass errno from a failing C function up multiple
// callers.
//
// ResultError can also directly construct a Result<T>. This is particularly useful if you have a
// function that return Result<T> but you have a Result<U> and want to return its error. In this
// case, you can return the .error() from the Result<U> to construct the Result<T>.
// An example of how to use these is below:
// Result<U> CalculateResult(const T& input) {
// U output;
// if (!SomeOtherCppFunction(input, &output)) {
// return Error() << "SomeOtherCppFunction(" << input << ") failed";
// }
// if (!c_api_function(output)) {
// return ErrnoError() << "c_api_function(" << output << ") failed";
// }
// return output;
// }
//
// auto output = CalculateResult(input);
// if (!output) return Error() << "CalculateResult failed: " << output.error();
// UseOutput(*output);
#pragma once
// The implementation of this file has moved to android-base. This file remains since historically,
// these classes were a part of init.
#include <android-base/result.h>
using android::base::ErrnoError;
using android::base::Error;
using android::base::Result;
using android::base::ResultError;
using android::base::Success;

View file

@ -43,14 +43,14 @@ namespace init {
// devices/configurations where these I/O operations are blocking for a long
// time. We do not reboot or halt on failures, as this is a best-effort
// attempt.
Result<Success> MixHwrngIntoLinuxRngAction(const BuiltinArguments&) {
Result<void> MixHwrngIntoLinuxRngAction(const BuiltinArguments&) {
unique_fd hwrandom_fd(
TEMP_FAILURE_RETRY(open("/dev/hw_random", O_RDONLY | O_NOFOLLOW | O_CLOEXEC)));
if (hwrandom_fd == -1) {
if (errno == ENOENT) {
LOG(INFO) << "/dev/hw_random not found";
// It's not an error to not have a Hardware RNG.
return Success();
return {};
}
return ErrnoError() << "Failed to open /dev/hw_random";
}
@ -80,7 +80,7 @@ Result<Success> MixHwrngIntoLinuxRngAction(const BuiltinArguments&) {
}
LOG(INFO) << "Mixed " << total_bytes_written << " bytes from /dev/hw_random into /dev/urandom";
return Success();
return {};
}
static bool SetHighestAvailableOptionValue(std::string path, int min, int max) {
@ -147,31 +147,31 @@ static bool __attribute__((unused)) SetMmapRndBitsMin(int start, int min, bool c
// 9e08f57d684a x86: mm: support ARCH_MMAP_RND_BITS
// ec9ee4acd97c drivers: char: random: add get_random_long()
// 5ef11c35ce86 mm: ASLR: use get_random_long()
Result<Success> SetMmapRndBitsAction(const BuiltinArguments&) {
Result<void> SetMmapRndBitsAction(const BuiltinArguments&) {
// values are arch-dependent
#if defined(USER_MODE_LINUX)
// uml does not support mmap_rnd_bits
return Success();
return {};
#elif defined(__aarch64__)
// arm64 supports 18 - 33 bits depending on pagesize and VA_SIZE
if (SetMmapRndBitsMin(33, 24, false) && SetMmapRndBitsMin(16, 16, true)) {
return Success();
return {};
}
#elif defined(__x86_64__)
// x86_64 supports 28 - 32 bits
if (SetMmapRndBitsMin(32, 32, false) && SetMmapRndBitsMin(16, 16, true)) {
return Success();
return {};
}
#elif defined(__arm__) || defined(__i386__)
// check to see if we're running on 64-bit kernel
bool h64 = !access(MMAP_RND_COMPAT_PATH, F_OK);
// supported 32-bit architecture must have 16 bits set
if (SetMmapRndBitsMin(16, 16, h64)) {
return Success();
return {};
}
#elif defined(__mips__) || defined(__mips64__)
// TODO: add mips support b/27788820
return Success();
return {};
#else
LOG(ERROR) << "Unknown architecture";
#endif
@ -187,14 +187,14 @@ Result<Success> SetMmapRndBitsAction(const BuiltinArguments&) {
// Set kptr_restrict to the highest available level.
//
// Aborts if unable to set this to an acceptable value.
Result<Success> SetKptrRestrictAction(const BuiltinArguments&) {
Result<void> SetKptrRestrictAction(const BuiltinArguments&) {
std::string path = KPTR_RESTRICT_PATH;
if (!SetHighestAvailableOptionValue(path, KPTR_RESTRICT_MINVALUE, KPTR_RESTRICT_MAXVALUE)) {
LOG(FATAL) << "Unable to set adequate kptr_restrict value!";
return Error();
}
return Success();
return {};
}
} // namespace init

View file

@ -26,9 +26,9 @@
namespace android {
namespace init {
Result<Success> MixHwrngIntoLinuxRngAction(const BuiltinArguments&);
Result<Success> SetMmapRndBitsAction(const BuiltinArguments&);
Result<Success> SetKptrRestrictAction(const BuiltinArguments&);
Result<void> MixHwrngIntoLinuxRngAction(const BuiltinArguments&);
Result<void> SetMmapRndBitsAction(const BuiltinArguments&);
Result<void> SetKptrRestrictAction(const BuiltinArguments&);
} // namespace init
} // namespace android

View file

@ -315,7 +315,7 @@ void Service::DumpState() const {
[] (const auto& info) { LOG(INFO) << *info; });
}
Result<Success> Service::ParseCapabilities(std::vector<std::string>&& args) {
Result<void> Service::ParseCapabilities(std::vector<std::string>&& args) {
capabilities_ = 0;
if (!CapAmbientSupported()) {
@ -341,32 +341,32 @@ Result<Success> Service::ParseCapabilities(std::vector<std::string>&& args) {
}
(*capabilities_)[cap] = true;
}
return Success();
return {};
}
Result<Success> Service::ParseClass(std::vector<std::string>&& args) {
Result<void> Service::ParseClass(std::vector<std::string>&& args) {
classnames_ = std::set<std::string>(args.begin() + 1, args.end());
return Success();
return {};
}
Result<Success> Service::ParseConsole(std::vector<std::string>&& args) {
Result<void> Service::ParseConsole(std::vector<std::string>&& args) {
flags_ |= SVC_CONSOLE;
proc_attr_.console = args.size() > 1 ? "/dev/" + args[1] : "";
return Success();
return {};
}
Result<Success> Service::ParseCritical(std::vector<std::string>&& args) {
Result<void> Service::ParseCritical(std::vector<std::string>&& args) {
flags_ |= SVC_CRITICAL;
return Success();
return {};
}
Result<Success> Service::ParseDisabled(std::vector<std::string>&& args) {
Result<void> Service::ParseDisabled(std::vector<std::string>&& args) {
flags_ |= SVC_DISABLED;
flags_ |= SVC_RC_DISABLED;
return Success();
return {};
}
Result<Success> Service::ParseEnterNamespace(std::vector<std::string>&& args) {
Result<void> Service::ParseEnterNamespace(std::vector<std::string>&& args) {
if (args[1] != "net") {
return Error() << "Init only supports entering network namespaces";
}
@ -377,10 +377,10 @@ Result<Success> Service::ParseEnterNamespace(std::vector<std::string>&& args) {
// present. Therefore, they also require mount namespaces.
namespaces_.flags |= CLONE_NEWNS;
namespaces_.namespaces_to_enter.emplace_back(CLONE_NEWNET, std::move(args[2]));
return Success();
return {};
}
Result<Success> Service::ParseGroup(std::vector<std::string>&& args) {
Result<void> Service::ParseGroup(std::vector<std::string>&& args) {
auto gid = DecodeUid(args[1]);
if (!gid) {
return Error() << "Unable to decode GID for '" << args[1] << "': " << gid.error();
@ -394,10 +394,10 @@ Result<Success> Service::ParseGroup(std::vector<std::string>&& args) {
}
proc_attr_.supp_gids.emplace_back(*gid);
}
return Success();
return {};
}
Result<Success> Service::ParsePriority(std::vector<std::string>&& args) {
Result<void> Service::ParsePriority(std::vector<std::string>&& args) {
proc_attr_.priority = 0;
if (!ParseInt(args[1], &proc_attr_.priority,
static_cast<int>(ANDROID_PRIORITY_HIGHEST), // highest is negative
@ -405,10 +405,10 @@ Result<Success> Service::ParsePriority(std::vector<std::string>&& args) {
return Error() << StringPrintf("process priority value must be range %d - %d",
ANDROID_PRIORITY_HIGHEST, ANDROID_PRIORITY_LOWEST);
}
return Success();
return {};
}
Result<Success> Service::ParseInterface(std::vector<std::string>&& args) {
Result<void> Service::ParseInterface(std::vector<std::string>&& args) {
const std::string& interface_name = args[1];
const std::string& instance_name = args[2];
@ -436,10 +436,10 @@ Result<Success> Service::ParseInterface(std::vector<std::string>&& args) {
interfaces_.insert(fullname);
return Success();
return {};
}
Result<Success> Service::ParseIoprio(std::vector<std::string>&& args) {
Result<void> Service::ParseIoprio(std::vector<std::string>&& args) {
if (!ParseInt(args[2], &proc_attr_.ioprio_pri, 0, 7)) {
return Error() << "priority value must be range 0 - 7";
}
@ -454,10 +454,10 @@ Result<Success> Service::ParseIoprio(std::vector<std::string>&& args) {
return Error() << "ioprio option usage: ioprio <rt|be|idle> <0-7>";
}
return Success();
return {};
}
Result<Success> Service::ParseKeycodes(std::vector<std::string>&& args) {
Result<void> Service::ParseKeycodes(std::vector<std::string>&& args) {
auto it = args.begin() + 1;
if (args.size() == 2 && StartsWith(args[1], "$")) {
std::string expanded;
@ -468,7 +468,7 @@ Result<Success> Service::ParseKeycodes(std::vector<std::string>&& args) {
// If the property is not set, it defaults to none, in which case there are no keycodes
// for this service.
if (expanded == "none") {
return Success();
return {};
}
args = Split(expanded, ",");
@ -486,24 +486,24 @@ Result<Success> Service::ParseKeycodes(std::vector<std::string>&& args) {
return Error() << "invalid keycode: " << *it;
}
}
return Success();
return {};
}
Result<Success> Service::ParseOneshot(std::vector<std::string>&& args) {
Result<void> Service::ParseOneshot(std::vector<std::string>&& args) {
flags_ |= SVC_ONESHOT;
return Success();
return {};
}
Result<Success> Service::ParseOnrestart(std::vector<std::string>&& args) {
Result<void> Service::ParseOnrestart(std::vector<std::string>&& args) {
args.erase(args.begin());
int line = onrestart_.NumCommands() + 1;
if (auto result = onrestart_.AddCommand(std::move(args), line); !result) {
return Error() << "cannot add Onrestart command: " << result.error();
}
return Success();
return {};
}
Result<Success> Service::ParseNamespace(std::vector<std::string>&& args) {
Result<void> Service::ParseNamespace(std::vector<std::string>&& args) {
for (size_t i = 1; i < args.size(); i++) {
if (args[i] == "pid") {
namespaces_.flags |= CLONE_NEWPID;
@ -515,105 +515,105 @@ Result<Success> Service::ParseNamespace(std::vector<std::string>&& args) {
return Error() << "namespace must be 'pid' or 'mnt'";
}
}
return Success();
return {};
}
Result<Success> Service::ParseOomScoreAdjust(std::vector<std::string>&& args) {
Result<void> Service::ParseOomScoreAdjust(std::vector<std::string>&& args) {
if (!ParseInt(args[1], &oom_score_adjust_, -1000, 1000)) {
return Error() << "oom_score_adjust value must be in range -1000 - +1000";
}
return Success();
return {};
}
Result<Success> Service::ParseOverride(std::vector<std::string>&& args) {
Result<void> Service::ParseOverride(std::vector<std::string>&& args) {
override_ = true;
return Success();
return {};
}
Result<Success> Service::ParseMemcgSwappiness(std::vector<std::string>&& args) {
Result<void> Service::ParseMemcgSwappiness(std::vector<std::string>&& args) {
if (!ParseInt(args[1], &swappiness_, 0)) {
return Error() << "swappiness value must be equal or greater than 0";
}
return Success();
return {};
}
Result<Success> Service::ParseMemcgLimitInBytes(std::vector<std::string>&& args) {
Result<void> Service::ParseMemcgLimitInBytes(std::vector<std::string>&& args) {
if (!ParseInt(args[1], &limit_in_bytes_, 0)) {
return Error() << "limit_in_bytes value must be equal or greater than 0";
}
return Success();
return {};
}
Result<Success> Service::ParseMemcgLimitPercent(std::vector<std::string>&& args) {
Result<void> Service::ParseMemcgLimitPercent(std::vector<std::string>&& args) {
if (!ParseInt(args[1], &limit_percent_, 0)) {
return Error() << "limit_percent value must be equal or greater than 0";
}
return Success();
return {};
}
Result<Success> Service::ParseMemcgLimitProperty(std::vector<std::string>&& args) {
Result<void> Service::ParseMemcgLimitProperty(std::vector<std::string>&& args) {
limit_property_ = std::move(args[1]);
return Success();
return {};
}
Result<Success> Service::ParseMemcgSoftLimitInBytes(std::vector<std::string>&& args) {
Result<void> Service::ParseMemcgSoftLimitInBytes(std::vector<std::string>&& args) {
if (!ParseInt(args[1], &soft_limit_in_bytes_, 0)) {
return Error() << "soft_limit_in_bytes value must be equal or greater than 0";
}
return Success();
return {};
}
Result<Success> Service::ParseProcessRlimit(std::vector<std::string>&& args) {
Result<void> Service::ParseProcessRlimit(std::vector<std::string>&& args) {
auto rlimit = ParseRlimit(args);
if (!rlimit) return rlimit.error();
proc_attr_.rlimits.emplace_back(*rlimit);
return Success();
return {};
}
Result<Success> Service::ParseRestartPeriod(std::vector<std::string>&& args) {
Result<void> Service::ParseRestartPeriod(std::vector<std::string>&& args) {
int period;
if (!ParseInt(args[1], &period, 5)) {
return Error() << "restart_period value must be an integer >= 5";
}
restart_period_ = std::chrono::seconds(period);
return Success();
return {};
}
Result<Success> Service::ParseSeclabel(std::vector<std::string>&& args) {
Result<void> Service::ParseSeclabel(std::vector<std::string>&& args) {
seclabel_ = std::move(args[1]);
return Success();
return {};
}
Result<Success> Service::ParseSigstop(std::vector<std::string>&& args) {
Result<void> Service::ParseSigstop(std::vector<std::string>&& args) {
sigstop_ = true;
return Success();
return {};
}
Result<Success> Service::ParseSetenv(std::vector<std::string>&& args) {
Result<void> Service::ParseSetenv(std::vector<std::string>&& args) {
environment_vars_.emplace_back(std::move(args[1]), std::move(args[2]));
return Success();
return {};
}
Result<Success> Service::ParseShutdown(std::vector<std::string>&& args) {
Result<void> Service::ParseShutdown(std::vector<std::string>&& args) {
if (args[1] == "critical") {
flags_ |= SVC_SHUTDOWN_CRITICAL;
return Success();
return {};
}
return Error() << "Invalid shutdown option";
}
Result<Success> Service::ParseTimeoutPeriod(std::vector<std::string>&& args) {
Result<void> Service::ParseTimeoutPeriod(std::vector<std::string>&& args) {
int period;
if (!ParseInt(args[1], &period, 1)) {
return Error() << "timeout_period value must be an integer >= 1";
}
timeout_period_ = std::chrono::seconds(period);
return Success();
return {};
}
template <typename T>
Result<Success> Service::AddDescriptor(std::vector<std::string>&& args) {
Result<void> Service::AddDescriptor(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;
@ -644,11 +644,11 @@ Result<Success> Service::AddDescriptor(std::vector<std::string>&& args) {
}
descriptors_.emplace_back(std::move(descriptor));
return Success();
return {};
}
// name type perm [ uid gid context ]
Result<Success> Service::ParseSocket(std::vector<std::string>&& args) {
Result<void> Service::ParseSocket(std::vector<std::string>&& args) {
if (!StartsWith(args[2], "dgram") && !StartsWith(args[2], "stream") &&
!StartsWith(args[2], "seqpacket")) {
return Error() << "socket type must be 'dgram', 'stream' or 'seqpacket'";
@ -657,7 +657,7 @@ Result<Success> Service::ParseSocket(std::vector<std::string>&& args) {
}
// name type perm [ uid gid context ]
Result<Success> Service::ParseFile(std::vector<std::string>&& args) {
Result<void> Service::ParseFile(std::vector<std::string>&& args) {
if (args[2] != "r" && args[2] != "w" && args[2] != "rw") {
return Error() << "file type must be 'r', 'w' or 'rw'";
}
@ -672,24 +672,24 @@ Result<Success> Service::ParseFile(std::vector<std::string>&& args) {
return AddDescriptor<FileInfo>(std::move(args));
}
Result<Success> Service::ParseUser(std::vector<std::string>&& args) {
Result<void> Service::ParseUser(std::vector<std::string>&& args) {
auto uid = DecodeUid(args[1]);
if (!uid) {
return Error() << "Unable to find UID for '" << args[1] << "': " << uid.error();
}
proc_attr_.uid = *uid;
return Success();
return {};
}
Result<Success> Service::ParseWritepid(std::vector<std::string>&& args) {
Result<void> Service::ParseWritepid(std::vector<std::string>&& args) {
args.erase(args.begin());
writepid_files_ = std::move(args);
return Success();
return {};
}
Result<Success> Service::ParseUpdatable(std::vector<std::string>&& args) {
Result<void> Service::ParseUpdatable(std::vector<std::string>&& args) {
updatable_ = true;
return Success();
return {};
}
class Service::OptionParserMap : public KeywordMap<OptionParser> {
@ -752,7 +752,7 @@ const Service::OptionParserMap::Map& Service::OptionParserMap::map() const {
return option_parsers;
}
Result<Success> Service::ParseLine(std::vector<std::string>&& args) {
Result<void> Service::ParseLine(std::vector<std::string>&& args) {
static const OptionParserMap parser_map;
auto parser = parser_map.FindFunction(args);
@ -761,7 +761,7 @@ Result<Success> Service::ParseLine(std::vector<std::string>&& args) {
return std::invoke(*parser, this, std::move(args));
}
Result<Success> Service::ExecStart() {
Result<void> Service::ExecStart() {
if (is_updatable() && !ServiceList::GetInstance().IsServicesUpdated()) {
// Don't delay the service for ExecStart() as the semantic is that
// the caller might depend on the side effect of the execution.
@ -782,10 +782,10 @@ Result<Success> Service::ExecStart() {
<< " gid " << proc_attr_.gid << "+" << proc_attr_.supp_gids.size() << " context "
<< (!seclabel_.empty() ? seclabel_ : "default") << ") started; waiting...";
return Success();
return {};
}
Result<Success> Service::Start() {
Result<void> Service::Start() {
if (is_updatable() && !ServiceList::GetInstance().IsServicesUpdated()) {
ServiceList::GetInstance().DelayService(*this);
return Error() << "Cannot start an updatable service '" << name_
@ -808,7 +808,7 @@ Result<Success> Service::Start() {
flags_ |= SVC_RESTART;
}
// It is not an error to try to start a service that is already running.
return Success();
return {};
}
bool needs_console = (flags_ & SVC_CONSOLE);
@ -960,24 +960,24 @@ Result<Success> Service::Start() {
}
NotifyStateChange("running");
return Success();
return {};
}
Result<Success> Service::StartIfNotDisabled() {
Result<void> Service::StartIfNotDisabled() {
if (!(flags_ & SVC_DISABLED)) {
return Start();
} else {
flags_ |= SVC_DISABLED_START;
}
return Success();
return {};
}
Result<Success> Service::Enable() {
Result<void> Service::Enable() {
flags_ &= ~(SVC_DISABLED | SVC_RC_DISABLED);
if (flags_ & SVC_DISABLED_START) {
return Start();
}
return Success();
return {};
}
void Service::Reset() {
@ -993,14 +993,14 @@ void Service::ResetIfPostData() {
}
}
Result<Success> Service::StartIfPostData() {
Result<void> Service::StartIfPostData() {
// Start the service, but only if it was started after /data was mounted,
// and it was still running when we reset the post-data services.
if (running_at_post_data_reset_) {
return Start();
}
return Success();
return {};
}
void Service::Stop() {
@ -1211,8 +1211,8 @@ void ServiceList::DelayService(const Service& service) {
delayed_service_names_.emplace_back(service.name());
}
Result<Success> ServiceParser::ParseSection(std::vector<std::string>&& args,
const std::string& filename, int line) {
Result<void> ServiceParser::ParseSection(std::vector<std::string>&& args,
const std::string& filename, int line) {
if (args.size() < 3) {
return Error() << "services must have a name and a program";
}
@ -1243,14 +1243,14 @@ Result<Success> ServiceParser::ParseSection(std::vector<std::string>&& args,
}
service_ = std::make_unique<Service>(name, restart_action_subcontext, str_args);
return Success();
return {};
}
Result<Success> ServiceParser::ParseLineSection(std::vector<std::string>&& args, int line) {
return service_ ? service_->ParseLine(std::move(args)) : Success();
Result<void> ServiceParser::ParseLineSection(std::vector<std::string>&& args, int line) {
return service_ ? service_->ParseLine(std::move(args)) : Result<void>{};
}
Result<Success> ServiceParser::EndSection() {
Result<void> ServiceParser::EndSection() {
if (service_) {
Service* old_service = service_list_->FindService(service_->name());
if (old_service) {
@ -1271,7 +1271,7 @@ Result<Success> ServiceParser::EndSection() {
service_list_->AddService(std::move(service_));
}
return Success();
return {};
}
bool ServiceParser::IsValidName(const std::string& name) const {

View file

@ -76,12 +76,12 @@ class Service {
static std::unique_ptr<Service> MakeTemporaryOneshotService(const std::vector<std::string>& args);
bool IsRunning() { return (flags_ & SVC_RUNNING) != 0; }
Result<Success> ParseLine(std::vector<std::string>&& args);
Result<Success> ExecStart();
Result<Success> Start();
Result<Success> StartIfNotDisabled();
Result<Success> StartIfPostData();
Result<Success> Enable();
Result<void> ParseLine(std::vector<std::string>&& args);
Result<void> ExecStart();
Result<void> Start();
Result<void> StartIfNotDisabled();
Result<void> StartIfPostData();
Result<void> Enable();
void Reset();
void ResetIfPostData();
void Stop();
@ -130,7 +130,7 @@ class Service {
bool is_post_data() const { return post_data_; }
private:
using OptionParser = Result<Success> (Service::*)(std::vector<std::string>&& args);
using OptionParser = Result<void> (Service::*)(std::vector<std::string>&& args);
class OptionParserMap;
void NotifyStateChange(const std::string& new_state) const;
@ -138,42 +138,42 @@ class Service {
void KillProcessGroup(int signal);
void SetProcessAttributesAndCaps();
Result<Success> ParseCapabilities(std::vector<std::string>&& args);
Result<Success> ParseClass(std::vector<std::string>&& args);
Result<Success> ParseConsole(std::vector<std::string>&& args);
Result<Success> ParseCritical(std::vector<std::string>&& args);
Result<Success> ParseDisabled(std::vector<std::string>&& args);
Result<Success> ParseEnterNamespace(std::vector<std::string>&& args);
Result<Success> ParseGroup(std::vector<std::string>&& args);
Result<Success> ParsePriority(std::vector<std::string>&& args);
Result<Success> ParseInterface(std::vector<std::string>&& args);
Result<Success> ParseIoprio(std::vector<std::string>&& args);
Result<Success> ParseKeycodes(std::vector<std::string>&& args);
Result<Success> ParseOneshot(std::vector<std::string>&& args);
Result<Success> ParseOnrestart(std::vector<std::string>&& args);
Result<Success> ParseOomScoreAdjust(std::vector<std::string>&& args);
Result<Success> ParseOverride(std::vector<std::string>&& args);
Result<Success> ParseMemcgLimitInBytes(std::vector<std::string>&& args);
Result<Success> ParseMemcgLimitPercent(std::vector<std::string>&& args);
Result<Success> ParseMemcgLimitProperty(std::vector<std::string>&& args);
Result<Success> ParseMemcgSoftLimitInBytes(std::vector<std::string>&& args);
Result<Success> ParseMemcgSwappiness(std::vector<std::string>&& args);
Result<Success> ParseNamespace(std::vector<std::string>&& args);
Result<Success> ParseProcessRlimit(std::vector<std::string>&& args);
Result<Success> ParseRestartPeriod(std::vector<std::string>&& args);
Result<Success> ParseSeclabel(std::vector<std::string>&& args);
Result<Success> ParseSetenv(std::vector<std::string>&& args);
Result<Success> ParseShutdown(std::vector<std::string>&& args);
Result<Success> ParseSigstop(std::vector<std::string>&& args);
Result<Success> ParseSocket(std::vector<std::string>&& args);
Result<Success> ParseTimeoutPeriod(std::vector<std::string>&& args);
Result<Success> ParseFile(std::vector<std::string>&& args);
Result<Success> ParseUser(std::vector<std::string>&& args);
Result<Success> ParseWritepid(std::vector<std::string>&& args);
Result<Success> ParseUpdatable(std::vector<std::string>&& args);
Result<void> ParseCapabilities(std::vector<std::string>&& args);
Result<void> ParseClass(std::vector<std::string>&& args);
Result<void> ParseConsole(std::vector<std::string>&& args);
Result<void> ParseCritical(std::vector<std::string>&& args);
Result<void> ParseDisabled(std::vector<std::string>&& args);
Result<void> ParseEnterNamespace(std::vector<std::string>&& args);
Result<void> ParseGroup(std::vector<std::string>&& args);
Result<void> ParsePriority(std::vector<std::string>&& args);
Result<void> ParseInterface(std::vector<std::string>&& args);
Result<void> ParseIoprio(std::vector<std::string>&& args);
Result<void> ParseKeycodes(std::vector<std::string>&& args);
Result<void> ParseOneshot(std::vector<std::string>&& args);
Result<void> ParseOnrestart(std::vector<std::string>&& args);
Result<void> ParseOomScoreAdjust(std::vector<std::string>&& args);
Result<void> ParseOverride(std::vector<std::string>&& args);
Result<void> ParseMemcgLimitInBytes(std::vector<std::string>&& args);
Result<void> ParseMemcgLimitPercent(std::vector<std::string>&& args);
Result<void> ParseMemcgLimitProperty(std::vector<std::string>&& args);
Result<void> ParseMemcgSoftLimitInBytes(std::vector<std::string>&& args);
Result<void> ParseMemcgSwappiness(std::vector<std::string>&& args);
Result<void> ParseNamespace(std::vector<std::string>&& args);
Result<void> ParseProcessRlimit(std::vector<std::string>&& args);
Result<void> ParseRestartPeriod(std::vector<std::string>&& args);
Result<void> ParseSeclabel(std::vector<std::string>&& args);
Result<void> ParseSetenv(std::vector<std::string>&& args);
Result<void> ParseShutdown(std::vector<std::string>&& args);
Result<void> ParseSigstop(std::vector<std::string>&& args);
Result<void> ParseSocket(std::vector<std::string>&& args);
Result<void> ParseTimeoutPeriod(std::vector<std::string>&& args);
Result<void> ParseFile(std::vector<std::string>&& args);
Result<void> ParseUser(std::vector<std::string>&& args);
Result<void> ParseWritepid(std::vector<std::string>&& args);
Result<void> ParseUpdatable(std::vector<std::string>&& args);
template <typename T>
Result<Success> AddDescriptor(std::vector<std::string>&& args);
Result<void> AddDescriptor(std::vector<std::string>&& args);
static unsigned long next_start_order_;
static bool is_exec_service_running_;
@ -295,10 +295,10 @@ class ServiceParser : public SectionParser {
public:
ServiceParser(ServiceList* service_list, std::vector<Subcontext>* subcontexts)
: service_list_(service_list), subcontexts_(subcontexts), service_(nullptr) {}
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;
Result<Success> EndSection() override;
Result<void> ParseSection(std::vector<std::string>&& args, const std::string& filename,
int line) override;
Result<void> ParseLineSection(std::vector<std::string>&& args, int line) override;
Result<void> EndSection() override;
void EndFile() override { filename_ = ""; }
private:

View file

@ -42,7 +42,7 @@ namespace init {
namespace {
Result<Success> EnterNamespace(int nstype, const char* path) {
Result<void> EnterNamespace(int nstype, const char* path) {
auto fd = unique_fd{open(path, O_RDONLY | O_CLOEXEC)};
if (fd == -1) {
return ErrnoError() << "Could not open namespace at " << path;
@ -50,10 +50,10 @@ Result<Success> EnterNamespace(int nstype, const char* path) {
if (setns(fd, nstype) == -1) {
return ErrnoError() << "Could not setns() namespace at " << path;
}
return Success();
return {};
}
Result<Success> SetUpMountNamespace(bool remount_proc, bool remount_sys) {
Result<void> SetUpMountNamespace(bool remount_proc, bool remount_sys) {
constexpr unsigned int kSafeFlags = MS_NODEV | MS_NOEXEC | MS_NOSUID;
// Recursively remount / as slave like zygote does so unmounting and mounting /proc
@ -83,10 +83,10 @@ Result<Success> SetUpMountNamespace(bool remount_proc, bool remount_sys) {
return ErrnoError() << "Could not mount(/sys)";
}
}
return Success();
return {};
}
Result<Success> SetUpPidNamespace(const char* name) {
Result<void> SetUpPidNamespace(const char* name) {
if (prctl(PR_SET_NAME, name) == -1) {
return ErrnoError() << "Could not set name";
}
@ -116,7 +116,7 @@ Result<Success> SetUpPidNamespace(const char* name) {
}
_exit(WEXITSTATUS(init_exitstatus));
}
return Success();
return {};
}
void ZapStdio() {
@ -140,8 +140,7 @@ void OpenConsole(const std::string& console) {
} // namespace
Result<Success> EnterNamespaces(const NamespaceInfo& info, const std::string& name,
bool pre_apexd) {
Result<void> EnterNamespaces(const NamespaceInfo& info, const std::string& name, bool pre_apexd) {
for (const auto& [nstype, path] : info.namespaces_to_enter) {
if (auto result = EnterNamespace(nstype, path.c_str()); !result) {
return result;
@ -173,10 +172,10 @@ Result<Success> EnterNamespaces(const NamespaceInfo& info, const std::string& na
}
}
return Success();
return {};
}
Result<Success> SetProcessAttributes(const ProcessAttributes& attr) {
Result<void> SetProcessAttributes(const ProcessAttributes& attr) {
if (attr.ioprio_class != IoSchedClass_NONE) {
if (android_set_ioprio(getpid(), attr.ioprio_class, attr.ioprio_pri)) {
PLOG(ERROR) << "failed to set pid " << getpid() << " ioprio=" << attr.ioprio_class
@ -221,10 +220,10 @@ Result<Success> SetProcessAttributes(const ProcessAttributes& attr) {
return ErrnoError() << "setpriority failed";
}
}
return Success();
return {};
}
Result<Success> WritePidToFiles(std::vector<std::string>* files) {
Result<void> WritePidToFiles(std::vector<std::string>* files) {
// See if there were "writepid" instructions to write to files under cpuset path.
std::string cpuset_path;
if (CgroupGetControllerPath("cpuset", &cpuset_path)) {
@ -258,7 +257,7 @@ Result<Success> WritePidToFiles(std::vector<std::string>* files) {
return ErrnoError() << "couldn't write " << pid_str << " to " << file;
}
}
return Success();
return {};
}
} // namespace init

View file

@ -34,7 +34,7 @@ struct NamespaceInfo {
// Pair of namespace type, path to name.
std::vector<std::pair<int, std::string>> namespaces_to_enter;
};
Result<Success> EnterNamespaces(const NamespaceInfo& info, const std::string& name, bool pre_apexd);
Result<void> EnterNamespaces(const NamespaceInfo& info, const std::string& name, bool pre_apexd);
struct ProcessAttributes {
std::string console;
@ -46,9 +46,9 @@ struct ProcessAttributes {
std::vector<gid_t> supp_gids;
int priority;
};
Result<Success> SetProcessAttributes(const ProcessAttributes& attr);
Result<void> SetProcessAttributes(const ProcessAttributes& attr);
Result<Success> WritePidToFiles(std::vector<std::string>* files);
Result<void> WritePidToFiles(std::vector<std::string>* files);
} // namespace init
} // namespace android

View file

@ -72,7 +72,7 @@ Result<std::string> ReadMessage(int socket) {
}
template <typename T>
Result<Success> SendMessage(int socket, const T& message) {
Result<void> SendMessage(int socket, const T& message) {
std::string message_string;
if (!message.SerializeToString(&message_string)) {
return Error() << "Unable to serialize message";
@ -87,7 +87,7 @@ Result<Success> SendMessage(int socket, const T& message) {
result != static_cast<long>(message_string.size())) {
return ErrnoError() << "send() failed to send message contents";
}
return Success();
return {};
}
std::vector<std::pair<std::string, std::string>> properties_to_set;
@ -123,7 +123,7 @@ void SubcontextProcess::RunCommand(const SubcontextCommand::ExecuteCommand& exec
}
auto map_result = function_map_->FindFunction(args);
Result<Success> result;
Result<void> result;
if (!map_result) {
result = Error() << "Cannot find command: " << map_result.error();
} else {
@ -299,7 +299,7 @@ Result<SubcontextReply> Subcontext::TransmitMessage(const SubcontextCommand& sub
return subcontext_reply;
}
Result<Success> Subcontext::Execute(const std::vector<std::string>& args) {
Result<void> Subcontext::Execute(const std::vector<std::string>& args) {
auto subcontext_command = SubcontextCommand();
std::copy(
args.begin(), args.end(),
@ -329,7 +329,7 @@ Result<Success> Subcontext::Execute(const std::vector<std::string>& args) {
<< subcontext_reply->reply_case();
}
return Success();
return {};
}
Result<std::vector<std::string>> Subcontext::ExpandArgs(const std::vector<std::string>& args) {

View file

@ -42,7 +42,7 @@ class Subcontext {
Fork();
}
Result<Success> Execute(const std::vector<std::string>& args);
Result<void> Execute(const std::vector<std::string>& args);
Result<std::vector<std::string>> ExpandArgs(const std::vector<std::string>& args);
void Restart();

View file

@ -53,7 +53,7 @@ BENCHMARK(BenchmarkSuccess);
TestFunctionMap BuildTestFunctionMap() {
TestFunctionMap test_function_map;
test_function_map.Add("return_success", 0, 0, true,
[](const BuiltinArguments& args) { return Success(); });
[](const BuiltinArguments& args) { return Result<void>{}; });
return test_function_map;
}

View file

@ -175,14 +175,14 @@ TestFunctionMap BuildTestFunctionMap() {
TestFunctionMap test_function_map;
// For CheckDifferentPid
test_function_map.Add("return_pids_as_error", 0, 0, true,
[](const BuiltinArguments& args) -> Result<Success> {
[](const BuiltinArguments& args) -> Result<void> {
return Error() << getpid() << " " << getppid();
});
// For SetProp
test_function_map.Add("setprop", 2, 2, true, [](const BuiltinArguments& args) {
android::base::SetProperty(args[1], args[2]);
return Success();
return Result<void>{};
});
// For MultipleCommands
@ -190,26 +190,26 @@ TestFunctionMap BuildTestFunctionMap() {
auto words = std::make_shared<std::vector<std::string>>();
test_function_map.Add("add_word", 1, 1, true, [words](const BuiltinArguments& args) {
words->emplace_back(args[1]);
return Success();
return Result<void>{};
});
test_function_map.Add("return_words_as_error", 0, 0, true,
[words](const BuiltinArguments& args) -> Result<Success> {
[words](const BuiltinArguments& args) -> Result<void> {
return Error() << Join(*words, " ");
});
// For RecoverAfterAbort
test_function_map.Add("cause_log_fatal", 0, 0, true,
[](const BuiltinArguments& args) -> Result<Success> {
[](const BuiltinArguments& args) -> Result<void> {
return Error() << std::string(4097, 'f');
});
test_function_map.Add(
"generate_sane_error", 0, 0, true,
[](const BuiltinArguments& args) -> Result<Success> { return Error() << "Sane error!"; });
"generate_sane_error", 0, 0, true,
[](const BuiltinArguments& args) -> Result<void> { return Error() << "Sane error!"; });
// For ContextString
test_function_map.Add(
"return_context_as_error", 0, 0, true,
[](const BuiltinArguments& args) -> Result<Success> { return Error() << args.context; });
"return_context_as_error", 0, 0, true,
[](const BuiltinArguments& args) -> Result<void> { return Error() << args.context; });
return test_function_map;
}

View file

@ -14,13 +14,13 @@
* limitations under the License.
*/
#ifndef _INIT_TEST_FUNCTION_MAP_H
#define _INIT_TEST_FUNCTION_MAP_H
#pragma once
#include <string>
#include <vector>
#include "builtin_arguments.h"
#include "builtins.h"
#include "keyword_map.h"
namespace android {
@ -33,7 +33,7 @@ class TestFunctionMap : public KeywordFunctionMap {
void Add(const std::string& name, const BuiltinFunctionNoArgs function) {
Add(name, 0, 0, false, [function](const BuiltinArguments&) {
function();
return Success();
return Result<void>{};
});
}
@ -51,5 +51,3 @@ class TestFunctionMap : public KeywordFunctionMap {
} // namespace init
} // namespace android
#endif

View file

@ -29,9 +29,9 @@ using android::base::ParseByteCount;
namespace android {
namespace init {
Result<Success> ParsePermissionsLine(std::vector<std::string>&& args,
std::vector<SysfsPermissions>* out_sysfs_permissions,
std::vector<Permissions>* out_dev_permissions) {
Result<void> 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) {
return Error() << "/sys/ lines must have 5 entries";
@ -74,22 +74,22 @@ Result<Success> ParsePermissionsLine(std::vector<std::string>&& args,
} else {
out_dev_permissions->emplace_back(name, perm, uid, gid);
}
return Success();
return {};
}
Result<Success> ParseFirmwareDirectoriesLine(std::vector<std::string>&& args,
std::vector<std::string>* firmware_directories) {
Result<void> ParseFirmwareDirectoriesLine(std::vector<std::string>&& args,
std::vector<std::string>* firmware_directories) {
if (args.size() < 2) {
return Error() << "firmware_directories must have at least 1 entry";
}
std::move(std::next(args.begin()), args.end(), std::back_inserter(*firmware_directories));
return Success();
return {};
}
Result<Success> ParseModaliasHandlingLine(std::vector<std::string>&& args,
bool* enable_modalias_handling) {
Result<void> ParseModaliasHandlingLine(std::vector<std::string>&& args,
bool* enable_modalias_handling) {
if (args.size() != 2) {
return Error() << "modalias_handling lines take exactly one parameter";
}
@ -102,11 +102,11 @@ Result<Success> ParseModaliasHandlingLine(std::vector<std::string>&& args,
return Error() << "modalias_handling takes either 'enabled' or 'disabled' as a parameter";
}
return Success();
return {};
}
Result<Success> ParseUeventSocketRcvbufSizeLine(std::vector<std::string>&& args,
size_t* uevent_socket_rcvbuf_size) {
Result<void> ParseUeventSocketRcvbufSizeLine(std::vector<std::string>&& args,
size_t* uevent_socket_rcvbuf_size) {
if (args.size() != 2) {
return Error() << "uevent_socket_rcvbuf_size lines take exactly one parameter";
}
@ -118,27 +118,27 @@ Result<Success> ParseUeventSocketRcvbufSizeLine(std::vector<std::string>&& args,
*uevent_socket_rcvbuf_size = parsed_size;
return Success();
return {};
}
class SubsystemParser : public SectionParser {
public:
SubsystemParser(std::vector<Subsystem>* subsystems) : subsystems_(subsystems) {}
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;
Result<Success> EndSection() override;
Result<void> ParseSection(std::vector<std::string>&& args, const std::string& filename,
int line) override;
Result<void> ParseLineSection(std::vector<std::string>&& args, int line) override;
Result<void> EndSection() override;
private:
Result<Success> ParseDevName(std::vector<std::string>&& args);
Result<Success> ParseDirName(std::vector<std::string>&& args);
Result<void> ParseDevName(std::vector<std::string>&& args);
Result<void> ParseDirName(std::vector<std::string>&& args);
Subsystem subsystem_;
std::vector<Subsystem>* subsystems_;
};
Result<Success> SubsystemParser::ParseSection(std::vector<std::string>&& args,
const std::string& filename, int line) {
Result<void> SubsystemParser::ParseSection(std::vector<std::string>&& args,
const std::string& filename, int line) {
if (args.size() != 2) {
return Error() << "subsystems must have exactly one name";
}
@ -149,33 +149,33 @@ Result<Success> SubsystemParser::ParseSection(std::vector<std::string>&& args,
subsystem_ = Subsystem(std::move(args[1]));
return Success();
return {};
}
Result<Success> SubsystemParser::ParseDevName(std::vector<std::string>&& args) {
Result<void> SubsystemParser::ParseDevName(std::vector<std::string>&& args) {
if (args[1] == "uevent_devname") {
subsystem_.devname_source_ = Subsystem::DEVNAME_UEVENT_DEVNAME;
return Success();
return {};
}
if (args[1] == "uevent_devpath") {
subsystem_.devname_source_ = Subsystem::DEVNAME_UEVENT_DEVPATH;
return Success();
return {};
}
return Error() << "invalid devname '" << args[1] << "'";
}
Result<Success> SubsystemParser::ParseDirName(std::vector<std::string>&& args) {
Result<void> SubsystemParser::ParseDirName(std::vector<std::string>&& args) {
if (args[1].front() != '/') {
return Error() << "dirname '" << args[1] << " ' does not start with '/'";
}
subsystem_.dir_name_ = args[1];
return Success();
return {};
}
Result<Success> SubsystemParser::ParseLineSection(std::vector<std::string>&& args, int line) {
using OptionParser = Result<Success> (SubsystemParser::*)(std::vector<std::string> && args);
Result<void> SubsystemParser::ParseLineSection(std::vector<std::string>&& args, int line) {
using OptionParser = Result<void> (SubsystemParser::*)(std::vector<std::string> && args);
static class OptionParserMap : public KeywordMap<OptionParser> {
private:
@ -197,10 +197,10 @@ Result<Success> SubsystemParser::ParseLineSection(std::vector<std::string>&& arg
return std::invoke(*parser, this, std::move(args));
}
Result<Success> SubsystemParser::EndSection() {
Result<void> SubsystemParser::EndSection() {
subsystems_->emplace_back(std::move(subsystem_));
return Success();
return {};
}
UeventdConfiguration ParseConfig(const std::vector<std::string>& configs) {

View file

@ -197,7 +197,7 @@ static int OpenFile(const std::string& path, int flags, mode_t mode) {
return rc;
}
Result<Success> WriteFile(const std::string& path, const std::string& content) {
Result<void> WriteFile(const std::string& path, const std::string& content) {
android::base::unique_fd fd(TEMP_FAILURE_RETRY(
OpenFile(path, O_WRONLY | O_CREAT | O_NOFOLLOW | O_TRUNC | O_CLOEXEC, 0600)));
if (fd == -1) {
@ -206,7 +206,7 @@ Result<Success> WriteFile(const std::string& path, const std::string& content) {
if (!android::base::WriteStringToFd(content, fd)) {
return ErrnoError() << "Unable to write file contents";
}
return Success();
return {};
}
bool mkdir_recursive(const std::string& path, mode_t mode) {

View file

@ -42,7 +42,7 @@ int CreateSocket(const char* name, int type, bool passcred, mode_t perm, uid_t u
const char* socketcon);
Result<std::string> ReadFile(const std::string& path);
Result<Success> WriteFile(const std::string& path, const std::string& content);
Result<void> WriteFile(const std::string& path, const std::string& content);
Result<uid_t> DecodeUid(const std::string& name);