mirror of
https://github.com/topjohnwu/Magisk.git
synced 2025-02-21 12:48:29 +00:00
Replace parse_mnt with parse_mount_info
This commit is contained in:
parent
f80d5d858e
commit
9555380818
@ -345,45 +345,6 @@ void parse_prop_file(const char *file, const function<bool(string_view, string_v
|
|||||||
parse_prop_file(fp.get(), fn);
|
parse_prop_file(fp.get(), fn);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Original source: https://android.googlesource.com/platform/bionic/+/master/libc/bionic/mntent.cpp
|
|
||||||
// License: AOSP, full copyright notice please check original source
|
|
||||||
static struct mntent *compat_getmntent_r(FILE *fp, struct mntent *e, char *buf, int buf_len) {
|
|
||||||
memset(e, 0, sizeof(*e));
|
|
||||||
while (fgets(buf, buf_len, fp) != nullptr) {
|
|
||||||
// Entries look like "proc /proc proc rw,nosuid,nodev,noexec,relatime 0 0".
|
|
||||||
// That is: mnt_fsname mnt_dir mnt_type mnt_opts 0 0.
|
|
||||||
int fsname0, fsname1, dir0, dir1, type0, type1, opts0, opts1;
|
|
||||||
if (sscanf(buf, " %n%*s%n %n%*s%n %n%*s%n %n%*s%n %d %d",
|
|
||||||
&fsname0, &fsname1, &dir0, &dir1, &type0, &type1, &opts0, &opts1,
|
|
||||||
&e->mnt_freq, &e->mnt_passno) == 2) {
|
|
||||||
e->mnt_fsname = &buf[fsname0];
|
|
||||||
buf[fsname1] = '\0';
|
|
||||||
e->mnt_dir = &buf[dir0];
|
|
||||||
buf[dir1] = '\0';
|
|
||||||
e->mnt_type = &buf[type0];
|
|
||||||
buf[type1] = '\0';
|
|
||||||
e->mnt_opts = &buf[opts0];
|
|
||||||
buf[opts1] = '\0';
|
|
||||||
return e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void parse_mnt(const char *file, const function<bool(mntent*)> &fn) {
|
|
||||||
auto fp = sFILE(setmntent(file, "re"), endmntent);
|
|
||||||
if (fp) {
|
|
||||||
mntent mentry{};
|
|
||||||
char buf[4096];
|
|
||||||
// getmntent_r from system's libc.so is broken on old platform
|
|
||||||
// use the compat one instead
|
|
||||||
while (compat_getmntent_r(fp.get(), &mentry, buf, sizeof(buf))) {
|
|
||||||
if (!fn(&mentry))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<mount_info> parse_mount_info(const char *pid) {
|
std::vector<mount_info> parse_mount_info(const char *pid) {
|
||||||
char buf[PATH_MAX] = {};
|
char buf[PATH_MAX] = {};
|
||||||
ssprintf(buf, sizeof(buf), "/proc/%s/mountinfo", pid);
|
ssprintf(buf, sizeof(buf), "/proc/%s/mountinfo", pid);
|
||||||
|
@ -106,7 +106,6 @@ void parse_prop_file(const char *file,
|
|||||||
void frm_rf(int dirfd);
|
void frm_rf(int dirfd);
|
||||||
void clone_dir(int src, int dest);
|
void clone_dir(int src, int dest);
|
||||||
std::vector<mount_info> parse_mount_info(const char *pid);
|
std::vector<mount_info> parse_mount_info(const char *pid);
|
||||||
void parse_mnt(const char *file, const std::function<bool(mntent*)> &fn);
|
|
||||||
std::string find_apk_path(const char *pkg);
|
std::string find_apk_path(const char *pkg);
|
||||||
|
|
||||||
using sFILE = std::unique_ptr<FILE, decltype(&fclose)>;
|
using sFILE = std::unique_ptr<FILE, decltype(&fclose)>;
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#include <set>
|
||||||
#include <sys/mount.h>
|
#include <sys/mount.h>
|
||||||
#include <sys/sysmacros.h>
|
#include <sys/sysmacros.h>
|
||||||
#include <libgen.h>
|
#include <libgen.h>
|
||||||
@ -91,23 +92,17 @@ static int64_t setup_block() {
|
|||||||
static void switch_root(const string &path) {
|
static void switch_root(const string &path) {
|
||||||
LOGD("Switch root to %s\n", path.data());
|
LOGD("Switch root to %s\n", path.data());
|
||||||
int root = xopen("/", O_RDONLY);
|
int root = xopen("/", O_RDONLY);
|
||||||
vector<string> mounts;
|
for (set<string, greater<>> mounts; auto &info : parse_mount_info("self")) {
|
||||||
parse_mnt("/proc/mounts", [&](mntent *me) {
|
if (info.target == "/" || info.target == path)
|
||||||
// Skip root and self
|
continue;
|
||||||
if (me->mnt_dir == "/"sv || me->mnt_dir == path)
|
if (auto last_mount = mounts.upper_bound(info.target);
|
||||||
return true;
|
last_mount != mounts.end() && info.target.starts_with(*last_mount + '/')) {
|
||||||
// Do not include subtrees
|
continue;
|
||||||
for (const auto &m : mounts) {
|
|
||||||
if (strncmp(me->mnt_dir, m.data(), m.length()) == 0 && me->mnt_dir[m.length()] == '/')
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
mounts.emplace_back(me->mnt_dir);
|
mounts.emplace(info.target);
|
||||||
return true;
|
auto new_path = path + info.target;
|
||||||
});
|
|
||||||
for (auto &dir : mounts) {
|
|
||||||
auto new_path = path + dir;
|
|
||||||
xmkdir(new_path.data(), 0755);
|
xmkdir(new_path.data(), 0755);
|
||||||
xmount(dir.data(), new_path.data(), nullptr, MS_MOVE, nullptr);
|
xmount(info.target.data(), new_path.data(), nullptr, MS_MOVE, nullptr);
|
||||||
}
|
}
|
||||||
chdir(path.data());
|
chdir(path.data());
|
||||||
xmount(path.data(), "/", nullptr, MS_MOVE, nullptr);
|
xmount(path.data(), "/", nullptr, MS_MOVE, nullptr);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user