diff --git a/jni/daemon/bootstages.c b/jni/daemon/bootstages.c index 6f7101471..bfd181ddf 100644 --- a/jni/daemon/bootstages.c +++ b/jni/daemon/bootstages.c @@ -26,6 +26,8 @@ static char *buf, *buf2; static struct vector module_list; static int seperate_vendor = 0; +extern char **environ; + #ifdef MAGISK_DEBUG static int debug_log_pid, debug_log_fd; #endif @@ -114,14 +116,34 @@ static struct node_entry *insert_child(struct node_entry *p, struct node_entry * } /*********** - * Scripts * + * setenvs * ***********/ -static void bb_setenv() { - snprintf(buf, PATH_MAX, "%s:%s", BBPATH, getenv("PATH")); - setenv("PATH", buf, 1); +static void bb_setenv(struct vector *v) { + for (int i = 0; environ[i]; ++i) { + if (strncmp(environ[i], "PATH=", 5) == 0) { + snprintf(buf, PATH_MAX, "PATH=%s:%s", BBPATH, strchr(environ[i], '=') + 1); + vec_push_back(v, strdup(buf)); + } else { + vec_push_back(v, strdup(environ[i])); + } + } + vec_push_back(v, NULL); } +static void pm_setenv(struct vector *v) { + for (int i = 0; environ[i]; ++i) { + if (strncmp(environ[i], "CLASSPATH=", 10) != 0) + vec_push_back(v, strdup(environ[i])); + } + vec_push_back(v, strdup("CLASSPATH=/system/framework/pm.jar")); + vec_push_back(v, NULL); +} + +/*********** + * Scripts * + ***********/ + static void exec_common_script(const char* stage) { DIR *dir; struct dirent *entry; @@ -560,9 +582,8 @@ void post_fs_data(int client) { // uninstaller if (access(UNINSTALLER, F_OK) == 0) { close(open(UNBLOCKFILE, O_RDONLY | O_CREAT)); - bb_setenv(); setenv("BOOTMODE", "true", 1); - exec_command(0, NULL, NULL, "sh", UNINSTALLER, NULL); + exec_command(0, NULL, bb_setenv, "sh", UNINSTALLER, NULL); return; } @@ -669,10 +690,6 @@ unblock: unblock_boot_process(); } -static void pm_setenv() { - setenv("CLASSPATH", "/system/framework/pm.jar", 1); -} - void late_start(int client) { LOGI("** late_start service mode running\n"); // ack diff --git a/jni/include/utils.h b/jni/include/utils.h index 97901dea4..85b708a00 100644 --- a/jni/include/utils.h +++ b/jni/include/utils.h @@ -81,7 +81,7 @@ void ps_filter_proc_name(const char *filter, void (*func)(int)); int create_links(const char *bin, const char *path); void unlock_blocks(); void setup_sighandlers(void (*handler)(int)); -int exec_command(int err, int *fd, void (*cb)(void), const char *argv0, ...); +int exec_command(int err, int *fd, void (*setupenv)(struct vector*), const char *argv0, ...); int exec_command_sync(char *const argv0, ...); int mkdir_p(const char *pathname, mode_t mode); int bind_mount(const char *from, const char *to); diff --git a/jni/utils/misc.c b/jni/utils/misc.c index 4cf27c2b9..9721f5eab 100644 --- a/jni/utils/misc.c +++ b/jni/utils/misc.c @@ -226,7 +226,7 @@ void setup_sighandlers(void (*handler)(int)) { *fd >= 0 -> STDOUT (or STDERR) will be redirected to *fd *cb -> A callback function which runs after fork */ -static int v_exec_command(int err, int *fd, void (*cb)(void), const char *argv0, va_list argv) { +static int v_exec_command(int err, int *fd, void (*setupenv)(struct vector*), const char *argv0, va_list argv) { int pipefd[2], writeEnd = -1; if (fd) { @@ -240,12 +240,24 @@ static int v_exec_command(int err, int *fd, void (*cb)(void), const char *argv0, } // Collect va_list into vector - struct vector v; - vec_init(&v); - vec_push_back(&v, strdup(argv0)); + 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(&v, strdup(arg)); - vec_push_back(&v, NULL); + vec_push_back(&args, strdup(arg)); + vec_push_back(&args, NULL); + + // Setup environment + char *const *envp; + struct vector env; + vec_init(&env); + if (setupenv) { + setupenv(&env); + envp = (char **) vec_entry(&env); + } else { + extern char **environ; + envp = environ; + } int pid = fork(); if (pid != 0) { @@ -254,22 +266,21 @@ static int v_exec_command(int err, int *fd, void (*cb)(void), const char *argv0, *fd = pipefd[0]; close(pipefd[1]); } - vec_deep_destroy(&v); + vec_deep_destroy(&args); + vec_deep_destroy(&env); return pid; } // Don't return to the daemon if anything goes wrong err_handler = exit_proc; - if (cb) cb(); - if (fd) { xdup2(writeEnd, STDOUT_FILENO); if (err) xdup2(writeEnd, STDERR_FILENO); } - execvp(argv0, (char **) vec_entry(&v)); - PLOGE("execvp"); + execvpe(argv0, (char **) vec_entry(&args), envp); + PLOGE("execvpe"); return -1; } @@ -285,10 +296,10 @@ int exec_command_sync(char *const argv0, ...) { return WEXITSTATUS(status); } -int exec_command(int err, int *fd, void (*cb)(void), const char *argv0, ...) { +int exec_command(int err, int *fd, void (*setupenv)(struct vector*), const char *argv0, ...) { va_list argv; va_start(argv, argv0); - int pid = v_exec_command(err, fd, cb, argv0, argv); + int pid = v_exec_command(err, fd, setupenv, argv0, argv); va_end(argv); return pid; }