Merge "Fix adb tcpip tests."
diff --git a/base/Android.bp b/base/Android.bp
index 1395756..82aee2a 100644
--- a/base/Android.bp
+++ b/base/Android.bp
@@ -40,6 +40,10 @@
name: "libbase",
vendor_available: true,
host_supported: true,
+ vndk: {
+ enabled: true,
+ support_system_process: true,
+ },
srcs: [
"file.cpp",
"logging.cpp",
diff --git a/fastboot/fastboot.cpp b/fastboot/fastboot.cpp
index 49d9438..5f2267c 100644
--- a/fastboot/fastboot.cpp
+++ b/fastboot/fastboot.cpp
@@ -1463,7 +1463,7 @@
if (fs_generator_generate(gen, output.path, size, initial_dir,
eraseBlkSize, logicalBlkSize)) {
- fprintf(stderr, "Cannot generate image: %s\n", strerror(errno));
+ die("Cannot generate image for %s\n", partition);
return;
}
diff --git a/init/action.cpp b/init/action.cpp
index f687074..60204a8 100644
--- a/init/action.cpp
+++ b/init/action.cpp
@@ -91,14 +91,25 @@
auto result = command.InvokeFunc();
auto duration = t.duration();
+ // There are many legacy paths in rootdir/init.rc that will virtually never exist on a new
+ // device, such as '/sys/class/leds/jogball-backlight/brightness'. As of this writing, there
+ // are 198 such failures on bullhead. Instead of spamming the log reporting them, we do not
+ // report such failures unless we're running at the DEBUG log level.
+ bool report_failure = !result.has_value();
+ if (report_failure && android::base::GetMinimumLogSeverity() > android::base::DEBUG &&
+ result.error_errno() == ENOENT) {
+ report_failure = false;
+ }
+
// Any action longer than 50ms will be warned to user as slow operation
- if (duration > 50ms || android::base::GetMinimumLogSeverity() <= android::base::DEBUG) {
+ if (report_failure || duration > 50ms ||
+ android::base::GetMinimumLogSeverity() <= android::base::DEBUG) {
std::string trigger_name = BuildTriggersString();
std::string cmd_str = command.BuildCommandString();
LOG(INFO) << "Command '" << cmd_str << "' action=" << trigger_name << " (" << filename_
<< ":" << command.line() << ") took " << duration.count() << "ms and "
- << (result ? "succeeded" : "failed: " + result.error());
+ << (result ? "succeeded" : "failed: " + result.error_string());
}
}
diff --git a/init/builtins.cpp b/init/builtins.cpp
index f807343..54ccf09 100644
--- a/init/builtins.cpp
+++ b/init/builtins.cpp
@@ -127,7 +127,9 @@
Service* svc = ServiceList::GetInstance().FindService(args[1]);
if (!svc) return Error() << "Could not find service";
- if (!svc->Enable()) return Error() << "Could not enable service";
+ if (auto result = svc->Enable(); !result) {
+ return Error() << "Could not enable service: " << result.error();
+ }
return Success();
}
@@ -137,8 +139,8 @@
if (!service) {
return Error() << "Could not create exec service";
}
- if (!service->ExecStart()) {
- return Error() << "Could not start exec service";
+ if (auto result = service->ExecStart(); !result) {
+ return Error() << "Could not start exec service: " << result.error();
}
ServiceList::GetInstance().AddService(std::move(service));
@@ -151,16 +153,16 @@
return Error() << "Service not found";
}
- if (!service->ExecStart()) {
- return Error() << "Could not start Service";
+ if (auto result = service->ExecStart(); !result) {
+ return Error() << "Could not start exec service: " << result.error();
}
return Success();
}
static Result<Success> do_export(const std::vector<std::string>& args) {
- if (!add_environment(args[1].c_str(), args[2].c_str())) {
- return Error();
+ if (setenv(args[1].c_str(), args[2].c_str(), 1) == -1) {
+ return ErrnoError() << "setenv() failed";
}
return Success();
}
@@ -583,7 +585,9 @@
static Result<Success> do_start(const std::vector<std::string>& args) {
Service* svc = ServiceList::GetInstance().FindService(args[1]);
if (!svc) return Error() << "service " << args[1] << " not found";
- if (!svc->Start()) return Error() << "failed to start service";
+ if (auto result = svc->Start(); !result) {
+ return Error() << "Could not start service: " << result.error();
+ }
return Success();
}
@@ -608,6 +612,11 @@
static Result<Success> do_symlink(const std::vector<std::string>& args) {
if (symlink(args[1].c_str(), args[2].c_str()) < 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 ErrnoError() << "symlink() failed";
}
return Success();
diff --git a/init/descriptors.cpp b/init/descriptors.cpp
index cc5b948..6265687 100644
--- a/init/descriptors.cpp
+++ b/init/descriptors.cpp
@@ -28,7 +28,6 @@
#include <cutils/android_get_control_file.h>
#include <cutils/sockets.h>
-#include "init.h"
#include "util.h"
namespace android {
@@ -62,7 +61,7 @@
[] (char& c) { c = isalnum(c) ? c : '_'; });
std::string val = std::to_string(fd);
- add_environment(publishedName.c_str(), val.c_str());
+ setenv(publishedName.c_str(), val.c_str(), 1);
// make sure we don't close on exec
fcntl(fd, F_SETFD, 0);
diff --git a/init/init.cpp b/init/init.cpp
index d0afac1..e1bd3a2 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -71,8 +71,6 @@
std::string default_console = "/dev/console";
-const char *ENV[32];
-
static int epoll_fd = -1;
static std::unique_ptr<Timer> waiting_for_prop(nullptr);
@@ -126,38 +124,6 @@
}
}
-/* add_environment - add "key=value" to the current environment */
-int add_environment(const char *key, const char *val)
-{
- size_t n;
- size_t key_len = strlen(key);
-
- /* The last environment entry is reserved to terminate the list */
- for (n = 0; n < (arraysize(ENV) - 1); n++) {
-
- /* Delete any existing entry for this key */
- if (ENV[n] != NULL) {
- size_t entry_key_len = strcspn(ENV[n], "=");
- if ((entry_key_len == key_len) && (strncmp(ENV[n], key, entry_key_len) == 0)) {
- free((char*)ENV[n]);
- ENV[n] = NULL;
- }
- }
-
- /* Add entry if a free slot is available */
- if (ENV[n] == NULL) {
- char* entry;
- asprintf(&entry, "%s=%s", key, val);
- ENV[n] = entry;
- return 0;
- }
- }
-
- LOG(ERROR) << "No env. room to store: '" << key << "':'" << val << "'";
-
- return -1;
-}
-
bool start_waiting_for_property(const char *name, const char *value)
{
if (waiting_for_prop) {
@@ -429,8 +395,6 @@
install_reboot_signal_handlers();
}
- add_environment("PATH", _PATH_DEFPATH);
-
bool is_first_stage = (getenv("INIT_SECOND_STAGE") == nullptr);
if (is_first_stage) {
@@ -439,6 +403,8 @@
// Clear the umask.
umask(0);
+ clearenv();
+ setenv("PATH", _PATH_DEFPATH, 1);
// Get the basic filesystem setup we need put together in the initramdisk
// on / and then we'll let the rc file figure out the rest.
mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode=0755");
diff --git a/init/init.h b/init/init.h
index 50a7c83..b757c1d 100644
--- a/init/init.h
+++ b/init/init.h
@@ -30,9 +30,7 @@
// Note: These globals are *only* valid in init, so they should not be used in ueventd,
// watchdogd, or any files that may be included in those, such as devices.cpp and util.cpp.
// TODO: Have an Init class and remove all globals.
-extern const char *ENV[32];
extern std::string default_console;
-
extern std::vector<std::string> late_import_paths;
Parser CreateParser(ActionManager& action_manager, ServiceList& service_list);
@@ -43,8 +41,6 @@
void register_epoll_handler(int fd, void (*fn)());
-int add_environment(const char* key, const char* val);
-
bool start_waiting_for_property(const char *name, const char *value);
void DumpState();
diff --git a/init/result.h b/init/result.h
index 64fa69f..36c3b83 100644
--- a/init/result.h
+++ b/init/result.h
@@ -21,9 +21,13 @@
// 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 std::string describing an error, which can be accessed via
+// 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<Success> is the correct return type for a function that either returns successfully or
// returns an error value. Returning Success() from a function that returns Result<Success> is the
@@ -33,10 +37,20 @@
// 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. Each of these classes
-// take an ostream as an input and are implicitly cast to a Result<T> containing that failure.
-// ErrnoError() additionally appends ": " + strerror(errno) to the end of the failure string to aid
-// in interacting with C APIs.
+// 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) {
@@ -66,9 +80,29 @@
namespace android {
namespace init {
+struct ResultError {
+ template <typename T>
+ ResultError(T&& error_string, int error_errno)
+ : error_string(std::forward<T>(error_string)), error_errno(error_errno) {}
+
+ std::string error_string;
+ int error_errno;
+};
+
+inline std::ostream& operator<<(std::ostream& os, const ResultError& t) {
+ os << t.error_string;
+ return os;
+}
+
+inline std::ostream& operator<<(std::ostream& os, ResultError&& t) {
+ os << std::move(t.error_string);
+ return os;
+}
+
class Error {
public:
- Error() : append_errno_(0) {}
+ Error() : errno_(0), append_errno_(false) {}
+ Error(int errno_to_append) : errno_(errno_to_append), append_errno_(true) {}
template <typename T>
Error&& operator<<(T&& t) {
@@ -76,30 +110,45 @@
return std::move(*this);
}
- const std::string str() const {
- if (append_errno_) {
- return ss_.str() + ": " + strerror(append_errno_);
- }
- return ss_.str();
+ Error&& operator<<(const ResultError& result_error) {
+ ss_ << result_error.error_string;
+ errno_ = result_error.error_errno;
+ return std::move(*this);
}
+ Error&& operator<<(ResultError&& result_error) {
+ ss_ << std::move(result_error.error_string);
+ errno_ = result_error.error_errno;
+ return std::move(*this);
+ }
+
+ const std::string str() const {
+ std::string str = ss_.str();
+ if (append_errno_) {
+ if (str.empty()) {
+ return strerror(errno_);
+ }
+ return str + ": " + strerror(errno_);
+ }
+ return str;
+ }
+
+ int get_errno() const { return errno_; }
+
Error(const Error&) = delete;
Error(Error&&) = delete;
Error& operator=(const Error&) = delete;
Error& operator=(Error&&) = delete;
- protected:
- Error(int append_errno) : append_errno_(append_errno) {}
-
private:
std::stringstream ss_;
- int append_errno_;
+ int errno_;
+ bool append_errno_;
};
-class ErrnoError : public Error {
- public:
- ErrnoError() : Error(errno) {}
-};
+inline Error ErrnoError() {
+ return Error(errno);
+}
template <typename T>
class Result {
@@ -107,7 +156,13 @@
template <typename... U>
Result(U&&... result) : contents_(std::in_place_index_t<0>(), std::forward<U>(result)...) {}
- Result(Error&& fb) : contents_(std::in_place_index_t<1>(), fb.str()) {}
+ Result(Error&& error) : contents_(std::in_place_index_t<1>(), error.str(), error.get_errno()) {}
+ Result(const ResultError& result_error)
+ : contents_(std::in_place_index_t<1>(), result_error.error_string,
+ result_error.error_errno) {}
+ Result(ResultError&& result_error)
+ : contents_(std::in_place_index_t<1>(), std::move(result_error.error_string),
+ result_error.error_errno) {}
bool has_value() const { return contents_.index() == 0; }
@@ -116,9 +171,17 @@
T&& value() && { return std::get<0>(std::move(contents_)); }
const T&& value() const && { return std::get<0>(std::move(contents_)); }
- const std::string& error() const & { return std::get<1>(contents_); }
- std::string&& error() && { return std::get<1>(std::move(contents_)); }
- const std::string&& error() const && { return std::get<1>(std::move(contents_)); }
+ const ResultError& error() const & { return std::get<1>(contents_); }
+ ResultError&& error() && { return std::get<1>(std::move(contents_)); }
+ const ResultError&& error() const && { return std::get<1>(std::move(contents_)); }
+
+ const std::string& error_string() const & { return std::get<1>(contents_).error_string; }
+ std::string&& error_string() && { return std::get<1>(std::move(contents_)).error_string; }
+ const std::string&& error_string() const && {
+ return std::get<1>(std::move(contents_)).error_string;
+ }
+
+ int error_errno() const { return std::get<1>(contents_).error_errno; }
explicit operator bool() const { return has_value(); }
@@ -131,7 +194,7 @@
const T* operator->() const { return &value(); }
private:
- std::variant<T, std::string> contents_;
+ std::variant<T, ResultError> contents_;
};
using Success = std::monostate;
diff --git a/init/result_test.cpp b/init/result_test.cpp
index ca65013..19caaf5 100644
--- a/init/result_test.cpp
+++ b/init/result_test.cpp
@@ -74,7 +74,8 @@
ASSERT_FALSE(result);
ASSERT_FALSE(result.has_value());
- EXPECT_EQ("failure1", result.error());
+ EXPECT_EQ(0, result.error_errno());
+ EXPECT_EQ("failure1", result.error_string());
}
TEST(result, result_error_empty) {
@@ -82,7 +83,8 @@
ASSERT_FALSE(result);
ASSERT_FALSE(result.has_value());
- EXPECT_EQ("", result.error());
+ EXPECT_EQ(0, result.error_errno());
+ EXPECT_EQ("", result.error_string());
}
TEST(result, result_error_rvalue) {
@@ -96,7 +98,8 @@
ASSERT_FALSE(MakeRvalueErrorResult());
ASSERT_FALSE(MakeRvalueErrorResult().has_value());
- EXPECT_EQ("failure1", MakeRvalueErrorResult().error());
+ EXPECT_EQ(0, MakeRvalueErrorResult().error_errno());
+ EXPECT_EQ("failure1", MakeRvalueErrorResult().error_string());
}
TEST(result, result_errno_error) {
@@ -107,7 +110,72 @@
ASSERT_FALSE(result);
ASSERT_FALSE(result.has_value());
- EXPECT_EQ("failure1: "s + strerror(test_errno), result.error());
+ EXPECT_EQ(test_errno, result.error_errno());
+ EXPECT_EQ("failure1: "s + strerror(test_errno), result.error_string());
+}
+
+TEST(result, result_errno_error_no_text) {
+ constexpr int test_errno = 6;
+ errno = test_errno;
+ Result<Success> result = ErrnoError();
+
+ ASSERT_FALSE(result);
+ ASSERT_FALSE(result.has_value());
+
+ EXPECT_EQ(test_errno, result.error_errno());
+ EXPECT_EQ(strerror(test_errno), result.error_string());
+}
+
+TEST(result, result_error_from_other_result) {
+ auto error_text = "test error"s;
+ Result<Success> result = Error() << error_text;
+
+ ASSERT_FALSE(result);
+ ASSERT_FALSE(result.has_value());
+
+ Result<std::string> result2 = result.error();
+
+ ASSERT_FALSE(result2);
+ ASSERT_FALSE(result2.has_value());
+
+ EXPECT_EQ(0, result.error_errno());
+ EXPECT_EQ(error_text, result.error_string());
+}
+
+TEST(result, result_error_through_ostream) {
+ auto error_text = "test error"s;
+ Result<Success> result = Error() << error_text;
+
+ ASSERT_FALSE(result);
+ ASSERT_FALSE(result.has_value());
+
+ Result<std::string> result2 = Error() << result.error();
+
+ ASSERT_FALSE(result2);
+ ASSERT_FALSE(result2.has_value());
+
+ EXPECT_EQ(0, result.error_errno());
+ EXPECT_EQ(error_text, result.error_string());
+}
+
+TEST(result, result_errno_error_through_ostream) {
+ auto error_text = "test error"s;
+ constexpr int test_errno = 6;
+ errno = 6;
+ Result<Success> result = ErrnoError() << error_text;
+
+ errno = 0;
+
+ ASSERT_FALSE(result);
+ ASSERT_FALSE(result.has_value());
+
+ Result<std::string> result2 = Error() << result.error();
+
+ ASSERT_FALSE(result2);
+ ASSERT_FALSE(result2.has_value());
+
+ EXPECT_EQ(test_errno, result.error_errno());
+ EXPECT_EQ(error_text + ": " + strerror(test_errno), result.error_string());
}
TEST(result, constructor_forwarding) {
@@ -215,7 +283,7 @@
TEST(result, die_on_get_error_succesful_result) {
Result<std::string> result = "success";
- ASSERT_DEATH(result.error(), "");
+ ASSERT_DEATH(result.error_string(), "");
}
} // namespace init
diff --git a/init/selinux.cpp b/init/selinux.cpp
index c824028..ef59164 100644
--- a/init/selinux.cpp
+++ b/init/selinux.cpp
@@ -48,7 +48,6 @@
#include "selinux.h"
#include <fcntl.h>
-#include <paths.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>
@@ -126,8 +125,7 @@
}
TEMP_FAILURE_RETRY(close(pipe_fds[1]));
- const char* envp[] = {_PATH_DEFPATH, nullptr};
- if (execve(filename, argv, (char**)envp) == -1) {
+ if (execv(filename, argv) == -1) {
PLOG(ERROR) << "Failed to execve " << filename;
return false;
}
diff --git a/init/service.cpp b/init/service.cpp
index 6ab60e3..d3c9f92 100644
--- a/init/service.cpp
+++ b/init/service.cpp
@@ -57,22 +57,20 @@
namespace android {
namespace init {
-static std::string ComputeContextFromExecutable(std::string& service_name,
- const std::string& service_path) {
+static Result<std::string> ComputeContextFromExecutable(std::string& service_name,
+ const std::string& service_path) {
std::string computed_context;
char* raw_con = nullptr;
char* raw_filecon = nullptr;
if (getcon(&raw_con) == -1) {
- LOG(ERROR) << "could not get context while starting '" << service_name << "'";
- return "";
+ return Error() << "Could not get security context";
}
std::unique_ptr<char> mycon(raw_con);
if (getfilecon(service_path.c_str(), &raw_filecon) == -1) {
- LOG(ERROR) << "could not get file context while starting '" << service_name << "'";
- return "";
+ return Error() << "Could not get file context";
}
std::unique_ptr<char> filecon(raw_filecon);
@@ -84,12 +82,10 @@
free(new_con);
}
if (rc == 0 && computed_context == mycon.get()) {
- LOG(ERROR) << "service " << service_name << " does not have a SELinux domain defined";
- return "";
+ return Error() << "Service does not have an SELinux domain defined";
}
if (rc < 0) {
- LOG(ERROR) << "could not get context while starting '" << service_name << "'";
- return "";
+ return Error() << "Could not get process context";
}
return computed_context;
}
@@ -147,14 +143,6 @@
strs->push_back(nullptr);
}
-ServiceEnvironmentInfo::ServiceEnvironmentInfo() {
-}
-
-ServiceEnvironmentInfo::ServiceEnvironmentInfo(const std::string& name,
- const std::string& value)
- : name(name), value(value) {
-}
-
unsigned long Service::next_start_order_ = 1;
bool Service::is_exec_service_running_ = false;
@@ -507,7 +495,7 @@
}
Result<Success> Service::ParseSetenv(const std::vector<std::string>& args) {
- envvars_.emplace_back(args[1], args[2]);
+ environment_vars_.emplace_back(args[1], args[2]);
return Success();
}
@@ -637,16 +625,16 @@
static const OptionParserMap parser_map;
auto parser = parser_map.FindFunction(args);
- if (!parser) return Error() << parser.error();
+ if (!parser) return parser.error();
return std::invoke(*parser, this, args);
}
-bool Service::ExecStart() {
+Result<Success> Service::ExecStart() {
flags_ |= SVC_ONESHOT;
- if (!Start()) {
- return false;
+ if (auto result = Start(); !result) {
+ return result;
}
flags_ |= SVC_EXEC;
@@ -656,10 +644,10 @@
<< supp_gids_.size() << " context " << (!seclabel_.empty() ? seclabel_ : "default")
<< ") started; waiting...";
- return true;
+ return Success();
}
-bool Service::Start() {
+Result<Success> Service::Start() {
// Starting a service removes it from the disabled or reset state and
// immediately takes it out of the restarting state if it was in there.
flags_ &= (~(SVC_DISABLED|SVC_RESTARTING|SVC_RESET|SVC_RESTART|SVC_DISABLED_START));
@@ -668,7 +656,8 @@
// process of exiting, we've ensured that they will immediately restart
// on exit, unless they are ONESHOT.
if (flags_ & SVC_RUNNING) {
- return false;
+ // It is not an error to try to start a service that is already running.
+ return Success();
}
bool needs_console = (flags_ & SVC_CONSOLE);
@@ -681,28 +670,27 @@
// properly registered for the device node
int console_fd = open(console_.c_str(), O_RDWR | O_CLOEXEC);
if (console_fd < 0) {
- PLOG(ERROR) << "service '" << name_ << "' couldn't open console '" << console_ << "'";
flags_ |= SVC_DISABLED;
- return false;
+ return ErrnoError() << "Couldn't open console '" << console_ << "'";
}
close(console_fd);
}
struct stat sb;
if (stat(args_[0].c_str(), &sb) == -1) {
- PLOG(ERROR) << "cannot find '" << args_[0] << "', disabling '" << name_ << "'";
flags_ |= SVC_DISABLED;
- return false;
+ return ErrnoError() << "Cannot find '" << args_[0] << "'";
}
std::string scon;
if (!seclabel_.empty()) {
scon = seclabel_;
} else {
- scon = ComputeContextFromExecutable(name_, args_[0]);
- if (scon == "") {
- return false;
+ auto result = ComputeContextFromExecutable(name_, args_[0]);
+ if (!result) {
+ return result.error();
}
+ scon = *result;
}
LOG(INFO) << "starting service '" << name_ << "'...";
@@ -723,8 +711,8 @@
SetUpPidNamespace(name_);
}
- for (const auto& ei : envvars_) {
- add_environment(ei.name.c_str(), ei.value.c_str());
+ for (const auto& [key, value] : environment_vars_) {
+ setenv(key.c_str(), value.c_str(), 1);
}
std::for_each(descriptors_.begin(), descriptors_.end(),
@@ -779,7 +767,7 @@
std::vector<char*> strs;
ExpandArgs(args_, &strs);
- if (execve(strs[0], (char**) &strs[0], (char**) ENV) < 0) {
+ if (execv(strs[0], (char**)&strs[0]) < 0) {
PLOG(ERROR) << "cannot execve('" << strs[0] << "')";
}
@@ -787,9 +775,8 @@
}
if (pid < 0) {
- PLOG(ERROR) << "failed to fork for '" << name_ << "'";
pid_ = 0;
- return false;
+ return ErrnoError() << "Failed to fork";
}
if (oom_score_adjust_ != -1000) {
@@ -831,24 +818,24 @@
}
NotifyStateChange("running");
- return true;
+ return Success();
}
-bool Service::StartIfNotDisabled() {
+Result<Success> Service::StartIfNotDisabled() {
if (!(flags_ & SVC_DISABLED)) {
return Start();
} else {
flags_ |= SVC_DISABLED_START;
}
- return true;
+ return Success();
}
-bool Service::Enable() {
+Result<Success> Service::Enable() {
flags_ &= ~(SVC_DISABLED | SVC_RC_DISABLED);
if (flags_ & SVC_DISABLED_START) {
return Start();
}
- return true;
+ return Success();
}
void Service::Reset() {
@@ -874,7 +861,9 @@
StopOrReset(SVC_RESTART);
} else if (!(flags_ & SVC_RESTARTING)) {
/* Just start the service since it's not running. */
- Start();
+ if (auto result = Start(); !result) {
+ LOG(ERROR) << "Could not restart '" << name_ << "': " << result.error();
+ }
} /* else: Service is restarting anyways. */
}
diff --git a/init/service.h b/init/service.h
index fe85129..1f2c44f 100644
--- a/init/service.h
+++ b/init/service.h
@@ -57,13 +57,6 @@
namespace android {
namespace init {
-struct ServiceEnvironmentInfo {
- ServiceEnvironmentInfo();
- ServiceEnvironmentInfo(const std::string& name, const std::string& value);
- std::string name;
- std::string value;
-};
-
class Service {
public:
Service(const std::string& name, const std::vector<std::string>& args);
@@ -77,10 +70,10 @@
bool IsRunning() { return (flags_ & SVC_RUNNING) != 0; }
Result<Success> ParseLine(const std::vector<std::string>& args);
- bool ExecStart();
- bool Start();
- bool StartIfNotDisabled();
- bool Enable();
+ Result<Success> ExecStart();
+ Result<Success> Start();
+ Result<Success> StartIfNotDisabled();
+ Result<Success> Enable();
void Reset();
void Stop();
void Terminate();
@@ -178,7 +171,7 @@
std::string seclabel_;
std::vector<std::unique_ptr<DescriptorInfo>> descriptors_;
- std::vector<ServiceEnvironmentInfo> envvars_;
+ std::vector<std::pair<std::string, std::string>> environment_vars_;
Action onrestart_; // Commands to execute on restart.
diff --git a/init/util_test.cpp b/init/util_test.cpp
index 007d10e..3ae53a4 100644
--- a/init/util_test.cpp
+++ b/init/util_test.cpp
@@ -34,7 +34,7 @@
auto file_contents = ReadFile("/proc/does-not-exist");
EXPECT_EQ(ENOENT, errno);
ASSERT_FALSE(file_contents);
- EXPECT_EQ("open() failed: No such file or directory", file_contents.error());
+ EXPECT_EQ("open() failed: No such file or directory", file_contents.error_string());
}
TEST(util, ReadFileGroupWriteable) {
@@ -45,7 +45,7 @@
EXPECT_NE(-1, fchmodat(AT_FDCWD, tf.path, 0620, AT_SYMLINK_NOFOLLOW)) << strerror(errno);
auto file_contents = ReadFile(tf.path);
ASSERT_FALSE(file_contents) << strerror(errno);
- EXPECT_EQ("Skipping insecure file", file_contents.error());
+ EXPECT_EQ("Skipping insecure file", file_contents.error_string());
}
TEST(util, ReadFileWorldWiteable) {
@@ -56,7 +56,7 @@
EXPECT_NE(-1, fchmodat(AT_FDCWD, tf.path, 0602, AT_SYMLINK_NOFOLLOW)) << strerror(errno);
auto file_contents = ReadFile(tf.path);
ASSERT_FALSE(file_contents) << strerror(errno);
- EXPECT_EQ("Skipping insecure file", file_contents.error());
+ EXPECT_EQ("Skipping insecure file", file_contents.error_string());
}
TEST(util, ReadFileSymbolicLink) {
@@ -65,7 +65,7 @@
auto file_contents = ReadFile("/charger");
EXPECT_EQ(ELOOP, errno);
ASSERT_FALSE(file_contents);
- EXPECT_EQ("open() failed: Too many symbolic links encountered", file_contents.error());
+ EXPECT_EQ("open() failed: Too many symbolic links encountered", file_contents.error_string());
}
TEST(util, ReadFileSuccess) {
@@ -130,7 +130,7 @@
decoded_uid = DecodeUid("toot");
EXPECT_FALSE(decoded_uid);
- EXPECT_EQ("getpwnam failed: No such file or directory", decoded_uid.error());
+ EXPECT_EQ("getpwnam failed: No such file or directory", decoded_uid.error_string());
decoded_uid = DecodeUid("123");
EXPECT_TRUE(decoded_uid);
diff --git a/libbacktrace/Android.bp b/libbacktrace/Android.bp
index c58d777..02e0487 100644
--- a/libbacktrace/Android.bp
+++ b/libbacktrace/Android.bp
@@ -66,6 +66,10 @@
cc_library {
name: "libbacktrace",
vendor_available: true,
+ vndk: {
+ enabled: true,
+ support_system_process: true,
+ },
defaults: ["libbacktrace_common"],
host_supported: true,
diff --git a/libcutils/Android.bp b/libcutils/Android.bp
index 8528a4b..cfe8d29 100644
--- a/libcutils/Android.bp
+++ b/libcutils/Android.bp
@@ -50,6 +50,10 @@
cc_library {
name: "libcutils",
vendor_available: true,
+ vndk: {
+ enabled: true,
+ support_system_process: true,
+ },
host_supported: true,
srcs: [
"config_utils.c",
diff --git a/libion/Android.bp b/libion/Android.bp
index 6f267e4..6d9fae0 100644
--- a/libion/Android.bp
+++ b/libion/Android.bp
@@ -1,7 +1,11 @@
cc_library {
name: "libion",
- vendor_available: true,
+ vendor_available: true,
+ vndk: {
+ enabled: true,
+ support_system_process: true,
+ },
srcs: ["ion.c"],
shared_libs: ["liblog"],
local_include_dirs: [
diff --git a/libutils/Android.bp b/libutils/Android.bp
index 7d293ef..adcde81 100644
--- a/libutils/Android.bp
+++ b/libutils/Android.bp
@@ -44,6 +44,10 @@
cc_library {
name: "libutils",
vendor_available: true,
+ vndk: {
+ enabled: true,
+ support_system_process: true,
+ },
host_supported: true,
srcs: [