| diff --git a/Makefile.am b/Makefile.am |
| new file mode 100644 |
| index 0000000..7010370 |
| --- /dev/null |
| +++ b/Makefile.am |
| @@ -0,0 +1,2 @@ |
| +SUBDIRS = \ |
| + system/core/init |
| diff --git a/configure.ac b/configure.ac |
| new file mode 100644 |
| index 0000000..83b1988 |
| --- /dev/null |
| +++ b/configure.ac |
| @@ -0,0 +1,8 @@ |
| +AC_INIT([service-launcher], [1.0]) |
| +AM_INIT_AUTOMAKE([foreign]) |
| +AC_PROG_CXX |
| +AC_CONFIG_FILES([ |
| + Makefile |
| + system/core/init/Makefile |
| +]) |
| +AC_OUTPUT |
| diff --git a/system/core/init/Makefile.am b/system/core/init/Makefile.am |
| new file mode 100644 |
| index 0000000..adf9298 |
| --- /dev/null |
| +++ b/system/core/init/Makefile.am |
| @@ -0,0 +1,14 @@ |
| +bin_PROGRAMS = service-launcher |
| + |
| +service_launcher_CPPFLAGS = \ |
| + -I$(top_srcdir)/system/core/base/include |
| + |
| +service_launcher_CXXFLAGS = -std=c++14 |
| + |
| +service_launcher_SOURCES = \ |
| + $(top_srcdir)/system/core/base/stringprintf.cpp \ |
| + init_parser.cpp \ |
| + parser.cpp \ |
| + service.cpp \ |
| + service-launcher.cpp \ |
| + util.cpp |
| diff --git a/system/core/init/init_parser.cpp b/system/core/init/init_parser.cpp |
| index b44ca59..cc50f73 100644 |
| --- a/system/core/init/init_parser.cpp |
| +++ b/system/core/init/init_parser.cpp |
| @@ -18,7 +18,6 @@ |
| #include <errno.h> |
| #include <fcntl.h> |
| |
| -#include "action.h" |
| #include "init_parser.h" |
| #include "log.h" |
| #include "parser.h" |
| @@ -142,7 +141,9 @@ bool Parser::ParseConfig(const std::string& path) { |
| return ParseConfigFile(path); |
| } |
| |
| +#if 0 |
| void Parser::DumpState() const { |
| ServiceManager::GetInstance().DumpState(); |
| ActionManager::GetInstance().DumpState(); |
| } |
| +#endif |
| diff --git a/system/core/init/init_parser.h b/system/core/init/init_parser.h |
| index 5ed30ad..7310c35 100644 |
| --- a/system/core/init/init_parser.h |
| +++ b/system/core/init/init_parser.h |
| @@ -18,6 +18,7 @@ |
| #define _INIT_INIT_PARSER_H_ |
| |
| #include <map> |
| +#include <memory> |
| #include <string> |
| #include <vector> |
| |
| diff --git a/system/core/init/log.h b/system/core/init/log.h |
| index c5c30af..97776ed 100644 |
| --- a/system/core/init/log.h |
| +++ b/system/core/init/log.h |
| @@ -17,8 +17,6 @@ |
| #ifndef _INIT_LOG_H_ |
| #define _INIT_LOG_H_ |
| |
| -#include <cutils/klog.h> |
| - |
| #define ERROR(x...) init_klog_write(KLOG_ERROR_LEVEL, x) |
| #define WARNING(x...) init_klog_write(KLOG_WARNING_LEVEL, x) |
| #define NOTICE(x...) init_klog_write(KLOG_NOTICE_LEVEL, x) |
| @@ -26,7 +24,6 @@ |
| #define DEBUG(x...) init_klog_write(KLOG_DEBUG_LEVEL, x) |
| #define VERBOSE(x...) init_klog_write(KLOG_DEBUG_LEVEL, x) |
| |
| -void init_klog_write(int level, const char* fmt, ...) __printflike(2, 3); |
| -int selinux_klog_callback(int level, const char* fmt, ...) __printflike(2, 3); |
| +#define init_klog_write(level, x...) printf(x) |
| |
| #endif |
| diff --git a/system/core/init/service-launcher.cpp b/system/core/init/service-launcher.cpp |
| new file mode 100644 |
| index 0000000..9493384 |
| --- /dev/null |
| +++ b/system/core/init/service-launcher.cpp |
| @@ -0,0 +1,17 @@ |
| +#include <memory> |
| + |
| +#include "init_parser.h" |
| +#include "service.h" |
| + |
| +int main(int argc, char** argv) { |
| + |
| + if (argc != 2) { |
| + return 0; |
| + } |
| + |
| + Parser& parser = Parser::GetInstance(); |
| + parser.AddSectionParser("service",std::make_unique<ServiceParser>()); |
| + parser.ParseConfig(argv[1]); |
| + |
| + return 0; |
| +} |
| diff --git a/system/core/init/service.cpp b/system/core/init/service.cpp |
| index f5b8b00..20c2c9a 100644 |
| --- a/system/core/init/service.cpp |
| +++ b/system/core/init/service.cpp |
| @@ -23,22 +23,16 @@ |
| #include <termios.h> |
| #include <unistd.h> |
| |
| -#include <selinux/selinux.h> |
| - |
| -#include <android-base/file.h> |
| #include <android-base/stringprintf.h> |
| -#include <cutils/android_reboot.h> |
| #include <cutils/sockets.h> |
| |
| -#include "action.h" |
| -#include "init.h" |
| #include "init_parser.h" |
| #include "log.h" |
| -#include "property_service.h" |
| #include "util.h" |
| |
| using android::base::StringPrintf; |
| -using android::base::WriteStringToFile; |
| + |
| +#define add_environment(k, v) setenv(k, v, 1) |
| |
| #define CRITICAL_CRASH_THRESHOLD 4 // if we crash >4 times ... |
| #define CRITICAL_CRASH_WINDOW (4*60) // ... in 4 minutes, goto recovery |
| @@ -63,8 +57,7 @@ Service::Service(const std::string& name, const std::string& classname, |
| const std::vector<std::string>& args) |
| : name_(name), classname_(classname), flags_(0), pid_(0), time_started_(0), |
| time_crashed_(0), nr_crashed_(0), uid_(0), gid_(0), seclabel_(""), |
| - ioprio_class_(IoSchedClass_NONE), ioprio_pri_(0), args_(args) { |
| - onrestart_.InitSingleTrigger("onrestart"); |
| + args_(args) { |
| } |
| |
| Service::Service(const std::string& name, const std::string& classname, |
| @@ -72,10 +65,10 @@ Service::Service(const std::string& name, const std::string& classname, |
| const std::string& seclabel, const std::vector<std::string>& args) |
| : name_(name), classname_(classname), flags_(flags), pid_(0), time_started_(0), |
| time_crashed_(0), nr_crashed_(0), uid_(uid), gid_(gid), supp_gids_(supp_gids), |
| - seclabel_(seclabel), ioprio_class_(IoSchedClass_NONE), ioprio_pri_(0), args_(args) { |
| - onrestart_.InitSingleTrigger("onrestart"); |
| + seclabel_(seclabel), args_(args) { |
| } |
| |
| +#if 0 |
| void Service::NotifyStateChange(const std::string& new_state) const { |
| if ((flags_ & SVC_EXEC) != 0) { |
| // 'exec' commands don't have properties tracking their state. |
| @@ -151,6 +144,7 @@ bool Service::Reap() { |
| NotifyStateChange("restarting"); |
| return false; |
| } |
| +#endif |
| |
| void Service::DumpState() const { |
| INFO("service %s\n", name_.c_str()); |
| @@ -196,6 +190,7 @@ bool Service::HandleGroup(const std::vector<std::string>& args, std::string* err |
| } |
| |
| bool Service::HandleIoprio(const std::vector<std::string>& args, std::string* err) { |
| +#if 0 |
| ioprio_pri_ = std::stoul(args[2], 0, 8); |
| |
| if (ioprio_pri_ < 0 || ioprio_pri_ > 7) { |
| @@ -213,6 +208,7 @@ bool Service::HandleIoprio(const std::vector<std::string>& args, std::string* er |
| *err = "ioprio option usage: ioprio <rt|be|idle> <0-7>"; |
| return false; |
| } |
| +#endif |
| |
| return true; |
| } |
| @@ -230,8 +226,10 @@ bool Service::HandleOneshot(const std::vector<std::string>& args, std::string* e |
| } |
| |
| bool Service::HandleOnrestart(const std::vector<std::string>& args, std::string* err) { |
| +#if 0 |
| std::vector<std::string> str_args(args.begin() + 1, args.end()); |
| onrestart_.AddCommand(str_args, "", 0, err); |
| +#endif |
| return true; |
| } |
| |
| @@ -329,6 +327,7 @@ bool Service::Start() { |
| return false; |
| } |
| |
| +#if 0 |
| bool needs_console = (flags_ & SVC_CONSOLE); |
| if (needs_console) { |
| if (console_.empty()) { |
| @@ -343,6 +342,7 @@ bool Service::Start() { |
| return false; |
| } |
| } |
| +#endif |
| |
| struct stat sb; |
| if (stat(args_[0].c_str(), &sb) == -1) { |
| @@ -352,6 +352,7 @@ bool Service::Start() { |
| return false; |
| } |
| |
| +#if 0 |
| std::string scon; |
| if (!seclabel_.empty()) { |
| scon = seclabel_; |
| @@ -393,11 +394,14 @@ bool Service::Start() { |
| return false; |
| } |
| } |
| +#endif |
| |
| NOTICE("Starting service '%s'...\n", name_.c_str()); |
| |
| +#if 0 |
| pid_t pid = fork(); |
| if (pid == 0) { |
| +#endif |
| umask(077); |
| |
| for (const auto& ei : envvars_) { |
| @@ -408,8 +412,7 @@ bool Service::Start() { |
| int socket_type = ((si.type == "stream" ? SOCK_STREAM : |
| (si.type == "dgram" ? SOCK_DGRAM : |
| SOCK_SEQPACKET))); |
| - const char* socketcon = |
| - !si.socketcon.empty() ? si.socketcon.c_str() : scon.c_str(); |
| + const char* socketcon = nullptr; |
| |
| int s = create_socket(si.name.c_str(), socket_type, si.perm, |
| si.uid, si.gid, socketcon); |
| @@ -418,6 +421,7 @@ bool Service::Start() { |
| } |
| } |
| |
| +#if 0 |
| std::string pid_str = StringPrintf("%d", getpid()); |
| for (const auto& file : writepid_files_) { |
| if (!WriteStringToFile(pid_str, file)) { |
| @@ -468,17 +472,19 @@ bool Service::Start() { |
| _exit(127); |
| } |
| } |
| +#endif |
| |
| std::vector<char*> strs; |
| for (const auto& s : args_) { |
| strs.push_back(const_cast<char*>(s.c_str())); |
| } |
| strs.push_back(nullptr); |
| - if (execve(args_[0].c_str(), (char**) &strs[0], (char**) ENV) < 0) { |
| + if (execv(args_[0].c_str(), (char**) &strs[0]) < 0) { |
| ERROR("cannot execve('%s'): %s\n", args_[0].c_str(), strerror(errno)); |
| } |
| |
| _exit(127); |
| +#if 0 |
| } |
| |
| if (pid < 0) { |
| @@ -498,9 +504,11 @@ bool Service::Start() { |
| } |
| |
| NotifyStateChange("running"); |
| +#endif |
| return true; |
| } |
| |
| +#if 0 |
| bool Service::StartIfNotDisabled() { |
| if (!(flags_ & SVC_DISABLED)) { |
| return Start(); |
| @@ -608,6 +616,7 @@ void Service::OpenConsole() const { |
| dup2(fd, 2); |
| close(fd); |
| } |
| +#endif |
| |
| void Service::PublishSocket(const std::string& name, int fd) const { |
| std::string key = StringPrintf(ANDROID_SOCKET_ENV_PREFIX "%s", name.c_str()); |
| @@ -618,6 +627,7 @@ void Service::PublishSocket(const std::string& name, int fd) const { |
| fcntl(fd, F_SETFD, 0); |
| } |
| |
| +#if 0 |
| int ServiceManager::exec_count_ = 0; |
| |
| ServiceManager::ServiceManager() { |
| @@ -817,6 +827,7 @@ void ServiceManager::ReapAnyOutstandingChildren() { |
| while (ReapOneProcess()) { |
| } |
| } |
| +#endif |
| |
| bool ServiceParser::ParseSection(const std::vector<std::string>& args, |
| std::string* err) { |
| @@ -844,7 +855,7 @@ bool ServiceParser::ParseLineSection(const std::vector<std::string>& args, |
| |
| void ServiceParser::EndSection() { |
| if (service_) { |
| - ServiceManager::GetInstance().AddService(std::move(service_)); |
| + service_->Start(); |
| } |
| } |
| |
| diff --git a/system/core/init/service.h b/system/core/init/service.h |
| index d6ce664..1e36d3f 100644 |
| --- a/system/core/init/service.h |
| +++ b/system/core/init/service.h |
| @@ -19,13 +19,11 @@ |
| |
| #include <sys/types.h> |
| |
| -#include <cutils/iosched_policy.h> |
| - |
| +#include <limits> |
| #include <memory> |
| #include <string> |
| #include <vector> |
| |
| -#include "action.h" |
| #include "init_parser.h" |
| #include "keyword_map.h" |
| |
| @@ -145,17 +143,12 @@ private: |
| std::vector<SocketInfo> sockets_; |
| std::vector<ServiceEnvironmentInfo> envvars_; |
| |
| - Action onrestart_; // Commands to execute on restart. |
| - |
| std::vector<std::string> writepid_files_; |
| |
| // keycodes for triggering this service via /dev/keychord |
| std::vector<int> keycodes_; |
| int keychord_id_; |
| |
| - IoSchedClass ioprio_class_; |
| - int ioprio_pri_; |
| - |
| std::vector<std::string> args_; |
| }; |
| |
| diff --git a/system/core/init/util.cpp b/system/core/init/util.cpp |
| index 750e040..85e647f 100644 |
| --- a/system/core/init/util.cpp |
| +++ b/system/core/init/util.cpp |
| @@ -21,28 +21,22 @@ |
| #include <fcntl.h> |
| #include <ctype.h> |
| #include <errno.h> |
| +#include <limits.h> |
| #include <time.h> |
| #include <ftw.h> |
| #include <pwd.h> |
| - |
| -#include <selinux/label.h> |
| -#include <selinux/android.h> |
| +#include <unistd.h> |
| |
| #include <sys/stat.h> |
| #include <sys/types.h> |
| #include <sys/socket.h> |
| #include <sys/un.h> |
| |
| -#include <android-base/file.h> |
| -#include <android-base/strings.h> |
| - |
| /* for ANDROID_SOCKET_* */ |
| #include <cutils/sockets.h> |
| #include <android-base/stringprintf.h> |
| |
| -#include "init.h" |
| #include "log.h" |
| -#include "property_service.h" |
| #include "util.h" |
| |
| static unsigned int do_decode_uid(const char *s) |
| @@ -90,6 +84,7 @@ int create_socket(const char *name, int type, mode_t perm, uid_t uid, |
| { |
| struct sockaddr_un addr; |
| int fd, ret, savederrno; |
| +#if 0 |
| char *filecon; |
| |
| if (socketcon) { |
| @@ -98,6 +93,7 @@ int create_socket(const char *name, int type, mode_t perm, uid_t uid, |
| return -1; |
| } |
| } |
| +#endif |
| |
| fd = socket(PF_UNIX, type, 0); |
| if (fd < 0) { |
| @@ -105,8 +101,10 @@ int create_socket(const char *name, int type, mode_t perm, uid_t uid, |
| return -1; |
| } |
| |
| +#if 0 |
| if (socketcon) |
| setsockcreatecon(NULL); |
| +#endif |
| |
| memset(&addr, 0 , sizeof(addr)); |
| addr.sun_family = AF_UNIX; |
| @@ -119,18 +117,22 @@ int create_socket(const char *name, int type, mode_t perm, uid_t uid, |
| goto out_close; |
| } |
| |
| +#if 0 |
| filecon = NULL; |
| if (sehandle) { |
| ret = selabel_lookup(sehandle, &filecon, addr.sun_path, S_IFSOCK); |
| if (ret == 0) |
| setfscreatecon(filecon); |
| } |
| +#endif |
| |
| ret = bind(fd, (struct sockaddr *) &addr, sizeof (addr)); |
| savederrno = errno; |
| |
| +#if 0 |
| setfscreatecon(NULL); |
| freecon(filecon); |
| +#endif |
| |
| if (ret) { |
| ERROR("Failed to bind socket '%s': %s\n", name, strerror(savederrno)); |
| @@ -142,11 +144,13 @@ int create_socket(const char *name, int type, mode_t perm, uid_t uid, |
| ERROR("Failed to lchown socket '%s': %s\n", addr.sun_path, strerror(errno)); |
| goto out_unlink; |
| } |
| +#if 0 |
| ret = fchmodat(AT_FDCWD, addr.sun_path, perm, AT_SYMLINK_NOFOLLOW); |
| if (ret) { |
| ERROR("Failed to fchmodat socket '%s': %s\n", addr.sun_path, strerror(errno)); |
| goto out_unlink; |
| } |
| +#endif |
| |
| INFO("Created socket '%s' with mode '%o', user '%d', group '%d'\n", |
| addr.sun_path, perm, uid, gid); |
| @@ -180,11 +184,17 @@ bool read_file(const char* path, std::string* content) { |
| return false; |
| } |
| |
| - bool okay = android::base::ReadFdToString(fd, content); |
| + char buf[BUFSIZ]; |
| + ssize_t n; |
| + while ((n = TEMP_FAILURE_RETRY(read(fd, &buf[0], sizeof(buf)))) > 0) { |
| + content->append(buf, n); |
| + } |
| + bool okay = n == 0; |
| close(fd); |
| return okay; |
| } |
| |
| +#if 0 |
| int write_file(const char* path, const char* content) { |
| int fd = TEMP_FAILURE_RETRY(open(path, O_WRONLY|O_CREAT|O_NOFOLLOW|O_CLOEXEC, 0600)); |
| if (fd == -1) { |
| @@ -276,6 +286,7 @@ time_t gettime() { |
| clock_gettime(CLOCK_MONOTONIC, &now); |
| return now.tv_sec; |
| } |
| +#endif |
| |
| uint64_t gettime_ns() { |
| timespec now; |
| @@ -283,6 +294,7 @@ uint64_t gettime_ns() { |
| return static_cast<uint64_t>(now.tv_sec) * UINT64_C(1000000000) + now.tv_nsec; |
| } |
| |
| +#if 0 |
| int mkdir_recursive(const char *pathname, mode_t mode) |
| { |
| char buf[128]; |
| @@ -465,6 +477,7 @@ std::string bytes_to_hex(const uint8_t* bytes, size_t bytes_len) { |
| android::base::StringAppendF(&hex, "%02x", bytes[i]); |
| return hex; |
| } |
| +#endif |
| |
| /* |
| * Returns true is pathname is a directory |
| @@ -477,6 +490,7 @@ bool is_dir(const char* pathname) { |
| return S_ISDIR(info.st_mode); |
| } |
| |
| +#if 0 |
| bool expand_props(const std::string& src, std::string* dst) { |
| const char* src_ptr = src.c_str(); |
| |
| @@ -546,3 +560,4 @@ bool expand_props(const std::string& src, std::string* dst) { |
| |
| return true; |
| } |
| +#endif |