Rewrite exec_command

This commit is contained in:
topjohnwu 2019-01-26 13:39:24 -05:00
parent 7565ea2787
commit d32b788988
5 changed files with 45 additions and 86 deletions

View File

@ -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");
}
}

View File

@ -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;

View File

@ -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);

View File

@ -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 <string>
#include <vector>
#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<std::string> 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 <class ...Args>
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 <class ...Args>
int exec_command_sync(Args &&...args) {
const char *argv[] = {args..., nullptr};
return exec_command_sync(argv);
}
#endif

View File

@ -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<const char *> 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;
}