From d32b788988a0f5e881597caeeffec3d76e67a7b0 Mon Sep 17 00:00:00 2001 From: topjohnwu Date: Sat, 26 Jan 2019 13:39:24 -0500 Subject: [PATCH] Rewrite exec_command --- native/jni/daemon/bootstages.cpp | 23 ++++++-------- native/jni/daemon/log_daemon.cpp | 4 +-- native/jni/misc/img.cpp | 28 ++++++++--------- native/jni/utils/include/utils.h | 24 +++++++++++---- native/jni/utils/misc.cpp | 52 +------------------------------- 5 files changed, 45 insertions(+), 86 deletions(-) diff --git a/native/jni/daemon/bootstages.cpp b/native/jni/daemon/bootstages.cpp index 1c38e019f..112c22a69 100644 --- a/native/jni/daemon/bootstages.cpp +++ b/native/jni/daemon/bootstages.cpp @@ -323,9 +323,8 @@ static void exec_common_script(const char* stage) { if (access(entry->d_name, X_OK) == -1) continue; LOGI("%s.d: exec [%s]\n", stage, entry->d_name); - int pid = exec_command(false, nullptr, - strcmp(stage, "post-fs-data") ? set_path : set_mirror_path, - MIRRDIR "/system/bin/sh", entry->d_name, nullptr); + exec_t exec { .pre_exec = strcmp(stage, "post-fs-data") ? set_path : set_mirror_path }; + int pid = exec_command(exec, MIRRDIR "/system/bin/sh", entry->d_name); if (pid != -1) waitpid(pid, nullptr, 0); } @@ -342,9 +341,8 @@ static void exec_module_script(const char* stage) { if (access(buf2, F_OK) == -1) continue; LOGI("%s: exec [%s.sh]\n", module, stage); - int pid = exec_command(false, nullptr, - strcmp(stage, "post-fs-data") ? set_path : set_mirror_path, - MIRRDIR "/system/bin/sh", buf2, nullptr); + exec_t exec { .pre_exec = strcmp(stage, "post-fs-data") ? set_path : set_mirror_path }; + int pid = exec_command(exec, MIRRDIR "/system/bin/sh", buf2); if (pid != -1) waitpid(pid, nullptr, 0); } @@ -471,7 +469,7 @@ static bool magisk_env() { if (access(MIRRDIR "/bin/busybox", X_OK) == -1) return false; LOGI("* Setting up internal busybox"); - exec_command_sync(MIRRDIR "/bin/busybox", "--install", "-s", BBPATH, nullptr); + exec_command_sync(MIRRDIR "/bin/busybox", "--install", "-s", BBPATH); xsymlink(MIRRDIR "/bin/busybox", BBPATH "/busybox"); // Disable/remove magiskhide, resetprop, and modules @@ -557,11 +555,10 @@ static void install_apk(const char *apk) { while (true) { sleep(5); LOGD("apk_install: attempting to install APK\n"); - int fd = -1, pid; - pid = exec_command(true, &fd, nullptr, "/system/bin/sh", - "/system/bin/pm", "install", "-r", apk, nullptr); - FILE *res = fdopen(fd, "r"); + exec_t exec { .err = true, .fd = -1 }; + int pid = exec_command(exec, "/system/bin/pm", "install", "-r", apk); if (pid != -1) { + FILE *res = fdopen(exec.fd, "r"); bool err = false; while (fgets(buf, PATH_MAX, res)) { LOGD("apk_install: %s", buf); @@ -874,7 +871,7 @@ void late_start(int client) { // It's safe to create the folder at this point if the system didn't create it xmkdir(SECURE_DIR, 0700); // And reboot to make proper setup possible - exec_command_sync("/system/bin/reboot", nullptr); + exec_command_sync("/system/bin/reboot"); } auto_start_magiskhide(); @@ -901,7 +898,7 @@ core_only: get_db_strings(&str, SU_MANAGER); if (validate_manager(str[SU_MANAGER], 0, nullptr)) { // There is no manager installed, install the stub - exec_command_sync("/sbin/magiskinit", "-x", "manager", "/data/magisk.apk", nullptr); + exec_command_sync("/sbin/magiskinit", "-x", "manager", "/data/magisk.apk"); install_apk("/data/magisk.apk"); } } diff --git a/native/jni/daemon/log_daemon.cpp b/native/jni/daemon/log_daemon.cpp index e2196b5d3..3f8b1368c 100644 --- a/native/jni/daemon/log_daemon.cpp +++ b/native/jni/daemon/log_daemon.cpp @@ -134,7 +134,7 @@ static void log_daemon() { // Test whether these buffers actually works const char *b[] = { "main", "events", "crash" }; for (auto &buffer : b) { - if (exec_command_sync(MIRRDIR "/system/bin/logcat", "-b", buffer, "-d", "-f", "/dev/null", nullptr) == 0) { + if (exec_command_sync(MIRRDIR "/system/bin/logcat", "-b", buffer, "-d", "-f", "/dev/null") == 0) { log_cmd.push_back("-b"); log_cmd.push_back(buffer); } @@ -183,7 +183,7 @@ static void log_daemon() { bool start_log_daemon() { if (!log_daemon_started) { - if (exec_command_sync(MIRRDIR "/system/bin/logcat", "-d", "-f", "/dev/null", nullptr) == 0) { + if (exec_command_sync(MIRRDIR "/system/bin/logcat", "-d", "-f", "/dev/null") == 0) { if (fork_dont_care() == 0) log_daemon(); log_daemon_started = true; diff --git a/native/jni/misc/img.cpp b/native/jni/misc/img.cpp index 573b2532f..8379cc4f7 100644 --- a/native/jni/misc/img.cpp +++ b/native/jni/misc/img.cpp @@ -61,10 +61,10 @@ static char *loopsetup(const char *img) { } } if (lfd < 0) - return NULL; + return nullptr; ffd = xopen(img, O_RDWR); if (ioctl(lfd, LOOP_SET_FD, ffd) == -1) - return NULL; + return nullptr; strncpy((char *) info.lo_file_name, img, sizeof(info.lo_file_name)); ioctl(lfd, LOOP_SET_STATUS64, &info); close(lfd); @@ -122,7 +122,7 @@ int imgtool_main(int argc, char *argv[]) { xdup2(out, STDOUT_FILENO); close(fd); close(out); - if (loop == NULL) { + if (loop == nullptr) { fprintf(stderr, "Cannot mount image!\n"); return 1; } else { @@ -162,29 +162,29 @@ int create_img(const char *img, int size) { char size_str[16]; snprintf(size_str, sizeof(size_str), "%dM", size); if (access("/system/bin/make_ext4fs", X_OK) == 0) - return exec_command_sync("/system/bin/make_ext4fs", "-b", "4096", "-l", size_str, img, NULL); + return exec_command_sync("/system/bin/make_ext4fs", "-b", "4096", "-l", size_str, img); else if (access("/system/bin/mke2fs", X_OK) == 0) // On Android P there is no make_ext4fs, use mke2fs - return exec_command_sync("/system/bin/mke2fs", "-b", "4096", "-t", "ext4", img, size_str, NULL); + return exec_command_sync("/system/bin/mke2fs", "-b", "4096", "-t", "ext4", img, size_str); else return 1; } int resize_img(const char *img, int size) { LOGI("Resize %s to %dM\n", img, size); - exec_command_sync("/system/bin/e2fsck", "-yf", img, NULL); + exec_command_sync("/system/bin/e2fsck", "-yf", img); char ss[16]; snprintf(ss, sizeof(ss), "%dM", size); - return exec_command_sync("/system/bin/resize2fs", img, ss, NULL); + return exec_command_sync("/system/bin/resize2fs", img, ss); } char *mount_image(const char *img, const char *target) { if (access(img, F_OK) == -1 || access(target, F_OK) == -1) - return NULL; - exec_command_sync("/system/bin/e2fsck", "-yf", img, NULL); + return nullptr; + exec_command_sync("/system/bin/e2fsck", "-yf", img); char *device = loopsetup(img); if (device) - xmount(device, target, "ext4", MS_NOATIME, NULL); + xmount(device, target, "ext4", MS_NOATIME, nullptr); return device; } @@ -220,10 +220,10 @@ int merge_img(const char *source, const char *target) { xmkdir(TARGET_TMP, 0755); char *s_loop, *t_loop, *m_loop; s_loop = mount_image(source, SOURCE_TMP); - if (s_loop == NULL) + if (s_loop == nullptr) return 1; t_loop = mount_image(target, TARGET_TMP); - if (t_loop == NULL) + if (t_loop == nullptr) return 1; snprintf(buf, sizeof(buf), "%s/%s", SOURCE_TMP, "lost+found"); @@ -256,7 +256,7 @@ int merge_img(const char *source, const char *target) { create_img(buf, round_size(src.used + tgt.used)); xmkdir(MERGE_TMP, 0755); m_loop = mount_image(buf, MERGE_TMP); - if (m_loop == NULL) + if (m_loop == nullptr) return 1; LOGI("* Merging %s + %s -> %s", source, target, buf); @@ -288,7 +288,7 @@ int trim_img(const char *img, const char *mount, char *loop) { umount_image(mount, loop); resize_img(img, new_size); char *loop2 = mount_image(img, mount); - if (loop2 == NULL) + if (loop2 == nullptr) return 1; strcpy(loop, loop2); free(loop2); diff --git a/native/jni/utils/include/utils.h b/native/jni/utils/include/utils.h index 16bd1d69f..e8d9cfbcc 100644 --- a/native/jni/utils/include/utils.h +++ b/native/jni/utils/include/utils.h @@ -95,7 +95,7 @@ int __fsetxattr(int fd, const char *name, const void *value, size_t size, int fl // file.cpp -#define do_align(p, a) (((p) + (a) - 1) / (a) * (a)) +#define do_align(p, a) (((p) + (a) - 1) / (a) * (a)) #define align_off(p, a) (do_align(p, a) - (p)) extern const char **excl_list; @@ -138,24 +138,36 @@ void write_zero(int fd, size_t size); #include #include -#define str_contains(s, ss) ((ss) != nullptr && (s).find(ss) != string::npos) +#define str_contains(s, ss) ((ss) != nullptr && (s).find(ss) != std::string::npos) #define str_starts(s, ss) ((ss) != nullptr && (s).compare(0, strlen(ss), ss) == 0) +// file.cpp + std::vector file_to_vector(const char *filename); +// misc.cpp + struct exec_t { bool err = false; int fd = -2; void (*pre_exec)() = nullptr; - const char **argv = nullptr; int (*fork)() = xfork; + const char **argv = nullptr; }; int exec_command(exec_t &exec); -int exec_command(bool err, int *fd, void (*pre_exec)(), const char **argv); -int exec_command(bool err, int *fd, void (*cb)(), const char *argv0, ...); +template +int exec_command(exec_t &exec, Args &&...args) { + const char *argv[] = {args..., nullptr}; + exec.argv = argv; + return exec_command(exec); +} int exec_command_sync(const char **argv); -int exec_command_sync(const char *argv0, ...); +template +int exec_command_sync(Args &&...args) { + const char *argv[] = {args..., nullptr}; + return exec_command_sync(argv); +} #endif diff --git a/native/jni/utils/misc.cpp b/native/jni/utils/misc.cpp index 1f912f5a7..e947bb91e 100644 --- a/native/jni/utils/misc.cpp +++ b/native/jni/utils/misc.cpp @@ -195,39 +195,8 @@ int exec_command(exec_t &exec) { exit(-1); } -/* - fd == nullptr -> Ignore output - *fd < 0 -> Open pipe and set *fd to the read end - *fd >= 0 -> STDOUT (or STDERR) will be redirected to *fd - *pre_exec -> A callback function called after forking, before execvp -*/ -int exec_command(bool err, int *fd, void (*pre_exec)(), const char **argv) { - exec_t exec { - .err = err, - .fd = fd ? *fd : -2, - .pre_exec = pre_exec, - .argv = argv - }; - int pid = exec_command(exec); - if (fd) *fd = exec.fd; - return pid; -} - -static int v_exec_command(bool err, int *fd, void (*cb)(), const char *argv0, va_list argv) { - // Collect va_list into vector - vector args; - args.push_back(argv0); - for (const char *arg = va_arg(argv, char*); arg; arg = va_arg(argv, char*)) - args.push_back(arg); - args.push_back(nullptr); - int pid = exec_command(err, fd, cb, args.data()); - return pid; -} - int exec_command_sync(const char **argv) { - exec_t exec { - .argv = argv - }; + exec_t exec { .argv = argv }; int pid, status; pid = exec_command(exec); if (pid < 0) @@ -236,22 +205,3 @@ int exec_command_sync(const char **argv) { return WEXITSTATUS(status); } -int exec_command_sync(const char *argv0, ...) { - va_list argv; - va_start(argv, argv0); - int pid, status; - pid = v_exec_command(false, nullptr, nullptr, argv0, argv); - va_end(argv); - if (pid < 0) - return pid; - waitpid(pid, &status, 0); - return WEXITSTATUS(status); -} - -int exec_command(bool err, int *fd, void (*cb)(void), const char *argv0, ...) { - va_list argv; - va_start(argv, argv0); - int pid = v_exec_command(err, fd, cb, argv0, argv); - va_end(argv); - return pid; -}