Stop using chdir

This commit is contained in:
topjohnwu 2019-12-21 05:29:38 -05:00
parent 7668e45890
commit 3b9f7885e0
2 changed files with 27 additions and 26 deletions

View File

@ -451,47 +451,47 @@ static void reboot() {
void remove_modules() { void remove_modules() {
LOGI("* Remove all modules and reboot"); LOGI("* Remove all modules and reboot");
chdir(MODULEROOT); auto dir = xopen_dir(MODULEROOT);
rm_rf("lost+found"); int dfd = dirfd(dir.get());
auto dir = xopen_dir(".");
for (dirent *entry; (entry = xreaddir(dir.get()));) { for (dirent *entry; (entry = xreaddir(dir.get()));) {
if (entry->d_type == DT_DIR) { if (entry->d_type == DT_DIR) {
if (entry->d_name == "."sv || entry->d_name == ".."sv || entry->d_name == ".core"sv) if (entry->d_name == "."sv || entry->d_name == ".."sv || entry->d_name == ".core"sv)
continue; continue;
chdir(entry->d_name);
close(creat("remove", 0644)); int modfd = xopenat(dfd, entry->d_name, O_RDONLY | O_CLOEXEC);
chdir(".."); close(xopenat(modfd, "remove", O_RDONLY | O_CREAT | O_CLOEXEC));
close(modfd);
} }
} }
chdir("/");
reboot(); reboot();
} }
static void collect_modules() { static void collect_modules() {
chdir(MODULEROOT); auto dir = xopen_dir(MODULEROOT);
rm_rf("lost+found"); int dfd = dirfd(dir.get());
auto dir = xopen_dir(".");
for (dirent *entry; (entry = xreaddir(dir.get()));) { for (dirent *entry; (entry = xreaddir(dir.get()));) {
if (entry->d_type == DT_DIR) { if (entry->d_type == DT_DIR) {
if (entry->d_name == "."sv || entry->d_name == ".."sv || entry->d_name == ".core"sv) if (entry->d_name == "."sv || entry->d_name == ".."sv || entry->d_name == ".core"sv)
continue; continue;
chdir(entry->d_name);
if (access("remove", F_OK) == 0) { int modfd = xopenat(dfd, entry->d_name, O_RDONLY);
chdir(".."); run_finally f([=]{ close(modfd); });
if (faccessat(modfd, "remove", F_OK, 0) == 0) {
LOGI("%s: remove\n", entry->d_name); LOGI("%s: remove\n", entry->d_name);
sprintf(buf, "%s/uninstall.sh", entry->d_name); fd_pathat(modfd, "uninstall.sh", buf, sizeof(buf));
if (access(buf, F_OK) == 0) if (access(buf, F_OK) == 0)
exec_script(buf); exec_script(buf);
rm_rf(entry->d_name); frm_rf(modfd);
continue; continue;
} }
unlink("update");
if (access("disable", F_OK)) unlinkat(modfd, "update", 0);
if (faccessat(modfd, "disable", F_OK, 0) != 0)
module_list.emplace_back(entry->d_name); module_list.emplace_back(entry->d_name);
chdir("..");
} }
} }
chdir("/");
} }
static bool load_modules(node_entry *root) { static bool load_modules(node_entry *root) {

View File

@ -26,30 +26,31 @@ void exec_script(const char *script) {
void exec_common_script(const char *stage) { void exec_common_script(const char *stage) {
char path[4096]; char path[4096];
sprintf(path, SECURE_DIR "/%s.d", stage); char *name = path + sprintf(path, SECURE_DIR "/%s.d", stage);
auto dir = xopen_dir(path); auto dir = xopen_dir(path);
if (!dir) if (!dir)
return; return;
chdir(path);
int dfd = dirfd(dir.get());
bool pfs = stage == "post-fs-data"sv; bool pfs = stage == "post-fs-data"sv;
*(name++) = '/';
for (dirent *entry; (entry = xreaddir(dir.get()));) { for (dirent *entry; (entry = xreaddir(dir.get()));) {
if (entry->d_type == DT_REG) { if (entry->d_type == DT_REG) {
if (access(entry->d_name, X_OK) == -1) if (faccessat(dfd, entry->d_name, X_OK, 0) != 0)
continue; continue;
LOGI("%s.d: exec [%s]\n", stage, entry->d_name); LOGI("%s.d: exec [%s]\n", stage, entry->d_name);
strcpy(name, entry->d_name);
exec_t exec { exec_t exec {
.pre_exec = set_path, .pre_exec = set_path,
.fork = pfs ? fork_no_zombie : fork_dont_care .fork = pfs ? fork_no_zombie : fork_dont_care
}; };
if (pfs) if (pfs)
exec_command_sync(exec, "/system/bin/sh", entry->d_name); exec_command_sync(exec, "/system/bin/sh", path);
else else
exec_command(exec, "/system/bin/sh", entry->d_name); exec_command(exec, "/system/bin/sh", path);
} }
} }
chdir("/");
} }
void exec_module_script(const char *stage, const vector<string> &module_list) { void exec_module_script(const char *stage, const vector<string> &module_list) {