diff --git a/native/jni/daemon/bootstages.c b/native/jni/daemon/bootstages.c index 52ae20ade..fc97cf571 100644 --- a/native/jni/daemon/bootstages.c +++ b/native/jni/daemon/bootstages.c @@ -115,29 +115,15 @@ static struct node_entry *insert_child(struct node_entry *p, struct node_entry * * setenvs * ***********/ -static void set_path(struct vector *v) { +static void set_path() { char buffer[512]; - for (int i = 0; environ[i]; ++i) { - if (strncmp(environ[i], "PATH=", 5) == 0) { - sprintf(buffer, "PATH="BBPATH":%s", environ[i] + 5); - vec_push_back(v, strdup(buffer)); - } else { - vec_push_back(v, strdup(environ[i])); - } - } - vec_push_back(v, NULL); + sprintf(buffer, BBPATH ":%s", getenv("PATH")); + setenv("PATH", buffer, 1); } -static void set_mirror_path(struct vector *v) { - for (int i = 0; environ[i]; ++i) { - if (strncmp(environ[i], "PATH=", 5) == 0) { - vec_push_back(v, strdup("PATH="BBPATH":/sbin:"MIRRDIR"/system/bin:" - MIRRDIR"/system/xbin:"MIRRDIR"/vendor/bin")); - } else { - vec_push_back(v, strdup(environ[i])); - } - } - vec_push_back(v, NULL); +static void set_mirror_path() { + setenv("PATH", BBPATH ":/sbin:" MIRRDIR "/system/bin:" + MIRRDIR "/system/xbin:" MIRRDIR "/vendor/bin", 1); } /*********** diff --git a/native/jni/daemon/log_daemon.c b/native/jni/daemon/log_daemon.c index 1ac0c928a..f29bb0887 100644 --- a/native/jni/daemon/log_daemon.c +++ b/native/jni/daemon/log_daemon.c @@ -82,7 +82,7 @@ static void *logcat_thread(void *args) { char line[4096]; while (1) { // Start logcat - log_pid = exec_array(0, &log_fd, NULL, (char **) vec_entry(&log_cmd)); + log_pid = exec_array(0, &log_fd, NULL, (const char **) vec_entry(&log_cmd)); FILE *logs = fdopen(log_fd, "r"); while (fgets(line, sizeof(line), logs)) { if (line[0] == '-') @@ -103,7 +103,7 @@ static void *logcat_thread(void *args) { LOGI("magisklogd: logcat output EOF"); // Clear buffer - log_pid = exec_array(0, NULL, NULL, (char **) vec_entry(&clear_cmd)); + log_pid = exec_array(0, NULL, NULL, (const char **) vec_entry(&clear_cmd)); waitpid(log_pid, NULL, 0); } } diff --git a/native/jni/utils/include/array.h b/native/jni/utils/include/array.h index 41b468c14..9ad47aa5e 100644 --- a/native/jni/utils/include/array.h +++ b/native/jni/utils/include/array.h @@ -125,6 +125,10 @@ public: qsort(_data, _size, sizeof(T), compare); } + T* data() { return _data; } + + const T* data() const { return _data; } + // void reserve(size_t n) { ... } // void resize(size_t n) { ... } diff --git a/native/jni/utils/include/utils.h b/native/jni/utils/include/utils.h index 07d07b008..b2da22d2a 100644 --- a/native/jni/utils/include/utils.h +++ b/native/jni/utils/include/utils.h @@ -90,9 +90,9 @@ int file_to_vector(const char* filename, struct vector *v); int vector_to_file(const char* filename, struct vector *v); ssize_t fdgets(char *buf, size_t size, int fd); int is_num(const char *s); -int exec_array(int err, int *fd, void (*setenv)(struct vector *), char *const *argv); -int exec_command(int err, int *fd, void (*setenv)(struct vector*), const char *argv0, ...); -int exec_command_sync(char *const argv0, ...); +int exec_array(int err, int *fd, void (*cb)(void), const char *argv[]); +int exec_command(int err, int *fd, void (*cb)(void), const char *argv0, ...); +int exec_command_sync(const char *argv0, ...); int switch_mnt_ns(int pid); int fork_dont_care(); void gen_rand_str(char *buf, int len); diff --git a/native/jni/utils/legacy.c b/native/jni/utils/legacy.c index 0e6137174..2207cc3b5 100644 --- a/native/jni/utils/legacy.c +++ b/native/jni/utils/legacy.c @@ -5,93 +5,6 @@ #include "utils.h" #include "logging.h" -/* - fd == NULL -> Ignore output - *fd < 0 -> Open pipe and set *fd to the read end - *fd >= 0 -> STDOUT (or STDERR) will be redirected to *fd - *setenv -> A callback function which sets up a vector of environment variables -*/ -int exec_array(int err, int *fd, void (*setenv)(struct vector *), char *const *argv) { - int pipefd[2], writeEnd = -1; - - if (fd) { - if (*fd < 0) { - if (xpipe2(pipefd, O_CLOEXEC) == -1) - return -1; - writeEnd = pipefd[1]; - } else { - writeEnd = *fd; - } - } - - // Setup environment - char **envp; - struct vector env; - vec_init(&env); - if (setenv) { - setenv(&env); - envp = (char **) vec_entry(&env); - } else { - extern char **environ; - envp = environ; - } - - int pid = xfork(); - if (pid != 0) { - if (fd && *fd < 0) { - // Give the read end and close write end - *fd = pipefd[0]; - close(pipefd[1]); - } - vec_deep_destroy(&env); - return pid; - } - - if (fd) { - xdup2(writeEnd, STDOUT_FILENO); - if (err) - xdup2(writeEnd, STDERR_FILENO); - } - - environ = envp; - execvp(argv[0], argv); - PLOGE("execvp %s", argv[0]); - return -1; -} - -static int v_exec_command(int err, int *fd, void (*setenv)(struct vector*), const char *argv0, va_list argv) { - // Collect va_list into vector - struct vector args; - vec_init(&args); - vec_push_back(&args, strdup(argv0)); - for (void *arg = va_arg(argv, void*); arg; arg = va_arg(argv, void*)) - vec_push_back(&args, strdup(arg)); - vec_push_back(&args, NULL); - int pid = exec_array(err, fd, setenv, (char **) vec_entry(&args)); - vec_deep_destroy(&args); - return pid; -} - -int exec_command_sync(char *const argv0, ...) { - va_list argv; - va_start(argv, argv0); - int pid, status; - pid = v_exec_command(0, NULL, NULL, argv0, argv); - va_end(argv); - if (pid < 0) - return pid; - waitpid(pid, &status, 0); - return WEXITSTATUS(status); -} - -int exec_command(int err, int *fd, void (*setenv)(struct vector*), const char *argv0, ...) { - va_list argv; - va_start(argv, argv0); - int pid = v_exec_command(err, fd, setenv, argv0, argv); - va_end(argv); - return pid; -} - /* All the string should be freed manually!! */ int file_to_vector(const char* filename, struct vector *v) { if (access(filename, R_OK) != 0) diff --git a/native/jni/utils/misc.cpp b/native/jni/utils/misc.cpp index b3d985fb9..50549e758 100644 --- a/native/jni/utils/misc.cpp +++ b/native/jni/utils/misc.cpp @@ -193,3 +193,78 @@ ssize_t __getline(char **lineptr, size_t *n, FILE *stream) { int __fsetxattr(int fd, const char *name, const void *value, size_t size, int flags) { return (int) syscall(__NR_fsetxattr, fd, name, value, size, flags); } + +/* + fd == NULL -> Ignore output + *fd < 0 -> Open pipe and set *fd to the read end + *fd >= 0 -> STDOUT (or STDERR) will be redirected to *fd + *cb -> A callback function which calls after forking +*/ +int exec_array(int err, int *fd, void (*cb)(void), const char *argv[]) { + int pipefd[2], write_end = -1; + + if (fd) { + if (*fd < 0) { + if (xpipe2(pipefd, O_CLOEXEC) == -1) + return -1; + write_end = pipefd[1]; + } else { + write_end = *fd; + } + } + + int pid = xfork(); + if (pid != 0) { + if (fd && *fd < 0) { + // Give the read end and close write end + *fd = pipefd[0]; + close(pipefd[1]); + } + return pid; + } + + if (fd) { + xdup2(write_end, STDOUT_FILENO); + if (err) + xdup2(write_end, STDERR_FILENO); + } + + // Setup environment + if (cb) + cb(); + + execvp(argv[0], (char **) argv); + PLOGE("execvp %s", argv[0]); + return -1; +} + +static int v_exec_command(int err, int *fd, void (*cb)(void), const char *argv0, va_list argv) { + // Collect va_list into vector + Array 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_array(err, fd, cb, args.data()); + return pid; +} + +int exec_command_sync(const char *argv0, ...) { + va_list argv; + va_start(argv, argv0); + int pid, status; + pid = v_exec_command(0, NULL, NULL, argv0, argv); + va_end(argv); + if (pid < 0) + return pid; + waitpid(pid, &status, 0); + return WEXITSTATUS(status); +} + +int exec_command(int 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; +}