de09d52328
init tries to propagate error information up to build context before logging errors. This is a good thing, however too often init has the overly verbose paradigm for error handling, below: bool CalculateResult(const T& input, U* output, std::string* err) bool CalculateAndUseResult(const T& input, std::string* err) { U output; std::string calculate_result_err; if (!CalculateResult(input, &output, &calculate_result_err)) { *err = "CalculateResult " + input + " failed: " + calculate_result_err; return false; } UseResult(output); return true; } Even more common are functions that return only true/false but also require passing a std::string* err in order to see the error message. This change introduces a Result<T> that is use to either hold a successful return value of type T or to hold an error message as a std::string. If the functional only returns success or a failure with an error message, Result<Success> may be used. The classes Error and ErrnoError are used to indicate a failed Result<T>. 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> 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. The end result is that the above code snippet is turned into the much clearer example below: Result<U> CalculateResult(const T& input); Result<Success> CalculateAndUseResult(const T& input) { auto output = CalculateResult(input); if (!output) { return Error() << "CalculateResult " << input << " failed: " << output.error(); } UseResult(*output); return Success(); } This change also makes this conversion for some of the util.cpp functions that used the old paradigm. Test: boot bullhead, init unit tests Change-Id: I1e7d3a8820a79362245041251057fbeed2f7979b
178 lines
4.2 KiB
Text
178 lines
4.2 KiB
Text
//
|
|
// Copyright (C) 2017 The Android Open Source Project
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
//
|
|
|
|
cc_defaults {
|
|
name: "init_defaults",
|
|
cpp_std: "experimental",
|
|
sanitize: {
|
|
misc_undefined: ["signed-integer-overflow"],
|
|
},
|
|
cppflags: [
|
|
"-DLOG_UEVENTS=0",
|
|
"-Wall",
|
|
"-Wextra",
|
|
"-Wno-unused-parameter",
|
|
"-Werror",
|
|
"-DALLOW_LOCAL_PROP_OVERRIDE=0",
|
|
"-DALLOW_PERMISSIVE_SELINUX=0",
|
|
"-DREBOOT_BOOTLOADER_ON_PANIC=0",
|
|
"-DWORLD_WRITABLE_KMSG=0",
|
|
"-DDUMP_ON_UMOUNT_FAILURE=0",
|
|
"-DSHUTDOWN_ZERO_TIMEOUT=0",
|
|
],
|
|
product_variables: {
|
|
debuggable: {
|
|
cppflags: [
|
|
"-UALLOW_LOCAL_PROP_OVERRIDE",
|
|
"-DALLOW_LOCAL_PROP_OVERRIDE=1",
|
|
"-UALLOW_PERMISSIVE_SELINUX",
|
|
"-DALLOW_PERMISSIVE_SELINUX=1",
|
|
"-UREBOOT_BOOTLOADER_ON_PANIC",
|
|
"-DREBOOT_BOOTLOADER_ON_PANIC=1",
|
|
"-UWORLD_WRITABLE_KMSG",
|
|
"-DWORLD_WRITABLE_KMSG=1",
|
|
"-UDUMP_ON_UMOUNT_FAILURE",
|
|
"-DDUMP_ON_UMOUNT_FAILURE=1",
|
|
],
|
|
},
|
|
eng: {
|
|
cppflags: [
|
|
"-USHUTDOWN_ZERO_TIMEOUT",
|
|
"-DSHUTDOWN_ZERO_TIMEOUT=1",
|
|
],
|
|
},
|
|
},
|
|
}
|
|
|
|
cc_library_static {
|
|
name: "libinit",
|
|
defaults: ["init_defaults"],
|
|
srcs: [
|
|
"action.cpp",
|
|
"capabilities.cpp",
|
|
"descriptors.cpp",
|
|
"devices.cpp",
|
|
"firmware_handler.cpp",
|
|
"import_parser.cpp",
|
|
"log.cpp",
|
|
"parser.cpp",
|
|
"property_service.cpp",
|
|
"security.cpp",
|
|
"selinux.cpp",
|
|
"service.cpp",
|
|
"tokenizer.cpp",
|
|
"uevent_listener.cpp",
|
|
"ueventd_parser.cpp",
|
|
"util.cpp",
|
|
],
|
|
whole_static_libs: ["libcap"],
|
|
static_libs: [
|
|
"libbase",
|
|
"libselinux",
|
|
"liblog",
|
|
"libprocessgroup",
|
|
"libfs_mgr",
|
|
],
|
|
include_dirs: [
|
|
"system/core/mkbootimg",
|
|
],
|
|
|
|
}
|
|
|
|
/*
|
|
This is not yet ready, see the below TODOs for what is missing
|
|
|
|
cc_binary {
|
|
// TODO: Missing,
|
|
//LOCAL_MODULE_PATH := $(TARGET_ROOT_OUT)
|
|
//LOCAL_UNSTRIPPED_PATH := $(TARGET_ROOT_OUT_UNSTRIPPED)
|
|
|
|
name: "init",
|
|
defaults: ["init_defaults"],
|
|
required: [
|
|
"e2fsdroid",
|
|
"mke2fs",
|
|
],
|
|
static_executable: true,
|
|
srcs: [
|
|
"bootchart.cpp",
|
|
"builtins.cpp",
|
|
"init.cpp",
|
|
"init_first_stage.cpp",
|
|
"keychords.cpp",
|
|
"reboot.cpp",
|
|
"signal_handler.cpp",
|
|
"ueventd.cpp",
|
|
"watchdogd.cpp",
|
|
],
|
|
static_libs: [
|
|
"libinit",
|
|
"libbootloader_message",
|
|
"libfs_mgr",
|
|
"libfec",
|
|
"libfec_rs",
|
|
"libsquashfs_utils",
|
|
"liblogwrap",
|
|
"libext4_utils",
|
|
"libcutils",
|
|
"libbase",
|
|
"libc",
|
|
"libselinux",
|
|
"liblog",
|
|
"libcrypto_utils",
|
|
"libcrypto",
|
|
"libc++_static",
|
|
"libdl",
|
|
"libsparse",
|
|
"libz",
|
|
"libprocessgroup",
|
|
"libavb",
|
|
"libkeyutils",
|
|
],
|
|
symlinks: [
|
|
"sbin/ueventd",
|
|
"sbin/watchdogd",
|
|
],
|
|
}
|
|
*/
|
|
|
|
// Tests
|
|
// ------------------------------------------------------------------------------
|
|
|
|
cc_test {
|
|
name: "init_tests",
|
|
defaults: ["init_defaults"],
|
|
srcs: [
|
|
"devices_test.cpp",
|
|
"init_test.cpp",
|
|
"property_service_test.cpp",
|
|
"result_test.cpp",
|
|
"service_test.cpp",
|
|
"ueventd_test.cpp",
|
|
"util_test.cpp",
|
|
],
|
|
shared_libs: [
|
|
"libbase",
|
|
"libcutils",
|
|
],
|
|
static_libs: [
|
|
"libinit",
|
|
"libselinux",
|
|
"libcrypto",
|
|
],
|
|
}
|
|
|
|
subdirs = ["*"]
|