diff --git a/native/jni/core/bootstages.cpp b/native/jni/core/bootstages.cpp
index 9e6f10c97..6c1ba2175 100644
--- a/native/jni/core/bootstages.cpp
+++ b/native/jni/core/bootstages.cpp
@@ -131,7 +131,7 @@ void node_entry::create_module_tree(const char *module) {
auto full_path = get_path();
snprintf(buf, PATH_MAX, "%s/%s%s", MODULEROOT, module, full_path.c_str());
- unique_ptr
dir(xopendir(buf), closedir);
+ auto dir = xopen_dir(buf);
if (!dir)
return;
@@ -148,7 +148,7 @@ void node_entry::create_module_tree(const char *module) {
return;
}
- for (struct dirent *entry; (entry = xreaddir(dir.get()));) {
+ for (dirent *entry; (entry = xreaddir(dir.get()));) {
if (entry->d_name == "."sv || entry->d_name == ".."sv)
continue;
// Create new node
@@ -207,22 +207,18 @@ void node_entry::create_module_tree(const char *module) {
}
void node_entry::clone_skeleton() {
- DIR *dir;
- struct dirent *entry;
-
// Clone the structure
auto full_path = get_path();
- snprintf(buf, PATH_MAX, "%s%s", MIRRDIR, full_path.c_str());
- if (!(dir = xopendir(buf)))
- return;
- while ((entry = xreaddir(dir))) {
- if (entry->d_name == "."sv || entry->d_name == ".."sv)
- continue;
- // Create dummy node
- auto dummy = new node_entry(entry->d_name, entry->d_type, IS_DUMMY);
- insert(dummy);
- }
- closedir(dir);
+ snprintf(buf, PATH_MAX, "%s%s", MIRRDIR, full_path.data());
+ if (auto dir = xopen_dir(buf); dir) {
+ for (dirent *entry; (entry = xreaddir(dir.get()));) {
+ if (entry->d_name == "."sv || entry->d_name == ".."sv)
+ continue;
+ // Create dummy node
+ auto dummy = new node_entry(entry->d_name, entry->d_type, IS_DUMMY);
+ insert(dummy);
+ }
+ } else { return; }
if (status & IS_SKEL) {
file_attr attr;
@@ -460,9 +456,8 @@ void remove_modules() {
LOGI("* Remove all modules and reboot");
chdir(MODULEROOT);
rm_rf("lost+found");
- DIR *dir = xopendir(".");
- struct dirent *entry;
- while ((entry = xreaddir(dir))) {
+ auto dir = xopen_dir(".");
+ for (dirent *entry; (entry = xreaddir(dir.get()));) {
if (entry->d_type == DT_DIR) {
if (entry->d_name == "."sv || entry->d_name == ".."sv || entry->d_name == ".core"sv)
continue;
@@ -471,7 +466,6 @@ void remove_modules() {
chdir("..");
}
}
- closedir(dir);
chdir("/");
reboot();
}
@@ -479,9 +473,8 @@ void remove_modules() {
static void collect_modules() {
chdir(MODULEROOT);
rm_rf("lost+found");
- DIR *dir = xopendir(".");
- struct dirent *entry;
- while ((entry = xreaddir(dir))) {
+ auto dir = xopen_dir(".");
+ for (dirent *entry; (entry = xreaddir(dir.get()));) {
if (entry->d_type == DT_DIR) {
if (entry->d_name == "."sv || entry->d_name == ".."sv || entry->d_name == ".core"sv)
continue;
@@ -501,7 +494,6 @@ static void collect_modules() {
chdir("..");
}
}
- closedir(dir);
chdir("/");
}
@@ -575,15 +567,14 @@ static bool check_data() {
}
void unlock_blocks() {
- DIR *dir;
- struct dirent *entry;
int fd, dev, OFF = 0;
- if (!(dir = xopendir("/dev/block")))
+ auto dir = xopen_dir("/dev/block");
+ if (!dir)
return;
- dev = dirfd(dir);
+ dev = dirfd(dir.get());
- while((entry = readdir(dir))) {
+ for (dirent *entry; (entry = readdir(dir.get()));) {
if (entry->d_type == DT_BLK) {
if ((fd = openat(dev, entry->d_name, O_RDONLY | O_CLOEXEC)) < 0)
continue;
@@ -592,7 +583,6 @@ void unlock_blocks() {
close(fd);
}
}
- closedir(dir);
}
static bool log_dump = false;
diff --git a/native/jni/core/daemon.cpp b/native/jni/core/daemon.cpp
index d923b1671..c772b3a8a 100644
--- a/native/jni/core/daemon.cpp
+++ b/native/jni/core/daemon.cpp
@@ -118,10 +118,10 @@ static void main_daemon() {
// Unmount pre-init patches
if (access(ROOTMNT, F_OK) == 0) {
- file_readline(ROOTMNT, [](auto line) -> bool {
+ file_readline(true, ROOTMNT, [](auto line) -> bool {
umount2(line.data(), MNT_DETACH);
return true;
- }, true);
+ });
}
LOGI(SHOW_VER(Magisk) " daemon started\n");
diff --git a/native/jni/core/scripting.cpp b/native/jni/core/scripting.cpp
index ccb4e8da7..070e9c3d2 100644
--- a/native/jni/core/scripting.cpp
+++ b/native/jni/core/scripting.cpp
@@ -26,15 +26,14 @@ void exec_script(const char *script) {
void exec_common_script(const char *stage) {
char path[4096];
- DIR *dir;
- struct dirent *entry;
sprintf(path, SECURE_DIR "/%s.d", stage);
- if (!(dir = xopendir(path)))
+ auto dir = xopen_dir(path);
+ if (!dir)
return;
chdir(path);
- bool pfs = strcmp(stage, "post-fs-data") == 0;
- while ((entry = xreaddir(dir))) {
+ bool pfs = stage == "post-fs-data"sv;
+ for (dirent *entry; (entry = xreaddir(dir.get()));) {
if (entry->d_type == DT_REG) {
if (access(entry->d_name, X_OK) == -1)
continue;
@@ -50,13 +49,12 @@ void exec_common_script(const char *stage) {
}
}
- closedir(dir);
chdir("/");
}
void exec_module_script(const char *stage, const vector &module_list) {
char path[4096];
- bool pfs = strcmp(stage, "post-fs-data") == 0;
+ bool pfs = stage == "post-fs-data"sv;
for (auto &m : module_list) {
const char* module = m.c_str();
sprintf(path, MODULEROOT "/%s/%s.sh", module, stage);
diff --git a/native/jni/init/init.cpp b/native/jni/init/init.cpp
index 23a3d6f06..394a4dded 100644
--- a/native/jni/init/init.cpp
+++ b/native/jni/init/init.cpp
@@ -197,10 +197,10 @@ int main(int argc, char *argv[]) {
return test_main(argc, argv);
#endif
- if (argc > 1 && strcmp(argv[1], "-x") == 0) {
- if (strcmp(argv[2], "magisk") == 0)
+ if (argc > 1 && argv[1] == "-x"sv) {
+ if (argv[2] == "magisk"sv)
return dump_magisk(argv[3], 0755);
- else if (strcmp(argv[2], "manager") == 0)
+ else if (argv[2] == "manager"sv)
return dump_manager(argv[3], 0644);
}
@@ -208,27 +208,28 @@ int main(int argc, char *argv[]) {
return 1;
setup_klog();
- if (argc > 1 && argv[1] == "selinux_setup"sv) {
- auto init = make_unique(argv);
- init->start();
- }
-
- cmdline cmd{};
- load_kernel_info(&cmd);
-
unique_ptr init;
- if (cmd.force_normal_boot) {
- init = make_unique(argv, &cmd);
- } else if (cmd.skip_initramfs) {
- init = make_unique(argv, &cmd);
+ cmdline cmd{};
+
+ if (argc > 1 && argv[1] == "selinux_setup"sv) {
+ init = make_unique(argv);
} else {
- decompress_ramdisk();
- if (access("/sbin/recovery", F_OK) == 0 || access("/system/bin/recovery", F_OK) == 0)
- init = make_unique(argv, &cmd);
- else if (access("/apex", F_OK) == 0)
- init = make_unique(argv, &cmd);
- else
- init = make_unique(argv, &cmd);
+ // This will also mount /sys and /proc
+ load_kernel_info(&cmd);
+
+ if (cmd.force_normal_boot) {
+ init = make_unique(argv, &cmd);
+ } else if (cmd.skip_initramfs) {
+ init = make_unique(argv, &cmd);
+ } else {
+ decompress_ramdisk();
+ if (access("/sbin/recovery", F_OK) == 0 || access("/system/bin/recovery", F_OK) == 0)
+ init = make_unique(argv, &cmd);
+ else if (access("/apex", F_OK) == 0)
+ init = make_unique(argv, &cmd);
+ else
+ init = make_unique(argv, &cmd);
+ }
}
// Run the main routine
diff --git a/native/jni/init/mount.cpp b/native/jni/init/mount.cpp
index 49b7a27e5..c8bcbc5bf 100644
--- a/native/jni/init/mount.cpp
+++ b/native/jni/init/mount.cpp
@@ -44,17 +44,15 @@ static void parse_device(devinfo *dev, const char *uevent) {
static void collect_devices() {
char path[128];
devinfo dev{};
- DIR *dir = xopendir("/sys/dev/block");
- if (dir == nullptr)
- return;
- for (dirent *entry; (entry = readdir(dir));) {
- if (entry->d_name == "."sv || entry->d_name == ".."sv)
- continue;
- sprintf(path, "/sys/dev/block/%s/uevent", entry->d_name);
- parse_device(&dev, path);
- dev_list.push_back(dev);
+ if (auto dir = xopen_dir("/sys/dev/block"); dir) {
+ for (dirent *entry; (entry = readdir(dir.get()));) {
+ if (entry->d_name == "."sv || entry->d_name == ".."sv)
+ continue;
+ sprintf(path, "/sys/dev/block/%s/uevent", entry->d_name);
+ parse_device(&dev, path);
+ dev_list.push_back(dev);
+ }
}
- closedir(dir);
}
static int64_t setup_block(bool write_block = true) {
diff --git a/native/jni/init/rootdir.cpp b/native/jni/init/rootdir.cpp
index 27fde186d..c1ab38c5b 100644
--- a/native/jni/init/rootdir.cpp
+++ b/native/jni/init/rootdir.cpp
@@ -426,17 +426,16 @@ static void patch_fstab(const string &fstab) {
#define FSR "/first_stage_ramdisk"
void ABFirstStageInit::prepare() {
- DIR *dir = xopendir(FSR);
+ auto dir = xopen_dir(FSR);
if (!dir)
return;
string fstab(FSR "/");
- for (dirent *de; (de = readdir(dir));) {
+ for (dirent *de; (de = xreaddir(dir.get()));) {
if (strstr(de->d_name, "fstab")) {
fstab += de->d_name;
break;
}
}
- closedir(dir);
if (fstab.length() == sizeof(FSR))
return;
@@ -453,14 +452,13 @@ void ABFirstStageInit::prepare() {
}
void AFirstStageInit::prepare() {
- DIR *dir = xopendir("/");
- for (dirent *de; (de = readdir(dir));) {
+ auto dir = xopen_dir("/");
+ for (dirent *de; (de = xreaddir(dir.get()));) {
if (strstr(de->d_name, "fstab")) {
patch_fstab(de->d_name);
break;
}
}
- closedir(dir);
// Move stuffs for next stage
xmkdir("/system", 0755);
diff --git a/native/jni/magiskboot/bootimg.cpp b/native/jni/magiskboot/bootimg.cpp
index 93745bb88..3ab44d753 100644
--- a/native/jni/magiskboot/bootimg.cpp
+++ b/native/jni/magiskboot/bootimg.cpp
@@ -22,14 +22,14 @@ uint32_t dyn_img_hdr::j32 = 0;
uint64_t dyn_img_hdr::j64 = 0;
static void decompress(format_t type, int fd, const void *in, size_t size) {
- auto ptr = get_decoder(type, make_stream(fd));
+ auto ptr = get_decoder(type, make_unique(fd));
ptr->write(in, size);
}
static off_t compress(format_t type, int fd, const void *in, size_t size) {
auto prev = lseek(fd, 0, SEEK_CUR);
{
- auto strm = get_encoder(type, make_stream(fd));
+ auto strm = get_encoder(type, make_unique(fd));
strm->write(in, size);
}
auto now = lseek(fd, 0, SEEK_CUR);
diff --git a/native/jni/magiskboot/compress.cpp b/native/jni/magiskboot/compress.cpp
index 8059aa3d1..ee5bae9b8 100644
--- a/native/jni/magiskboot/compress.cpp
+++ b/native/jni/magiskboot/compress.cpp
@@ -57,7 +57,7 @@ protected:
ENCODE
} mode;
- gz_strm(mode_t mode, sFILE &&fp) : cpr_stream(std::move(fp)), mode(mode) {
+ gz_strm(mode_t mode, stream_ptr &&base) : cpr_stream(std::move(base)), mode(mode) {
switch(mode) {
case DECODE:
inflateInit2(&strm, 15 | 16);
@@ -99,12 +99,12 @@ private:
class gz_decoder : public gz_strm {
public:
- explicit gz_decoder(sFILE &&fp) : gz_strm(DECODE, std::move(fp)) {};
+ explicit gz_decoder(stream_ptr &&base) : gz_strm(DECODE, std::move(base)) {};
};
class gz_encoder : public gz_strm {
public:
- explicit gz_encoder(sFILE &&fp) : gz_strm(ENCODE, std::move(fp)) {};
+ explicit gz_encoder(stream_ptr &&base) : gz_strm(ENCODE, std::move(base)) {};
};
class bz_strm : public cpr_stream {
@@ -131,7 +131,7 @@ protected:
ENCODE
} mode;
- bz_strm(mode_t mode, sFILE &&fp) : cpr_stream(std::move(fp)), mode(mode) {
+ bz_strm(mode_t mode, stream_ptr &&base) : cpr_stream(std::move(base)), mode(mode) {
switch(mode) {
case DECODE:
BZ2_bzDecompressInit(&strm, 0, 0);
@@ -173,12 +173,12 @@ private:
class bz_decoder : public bz_strm {
public:
- explicit bz_decoder(sFILE &&fp) : bz_strm(DECODE, std::move(fp)) {};
+ explicit bz_decoder(stream_ptr &&base) : bz_strm(DECODE, std::move(base)) {};
};
class bz_encoder : public bz_strm {
public:
- explicit bz_encoder(sFILE &&fp) : bz_strm(ENCODE, std::move(fp)) {};
+ explicit bz_encoder(stream_ptr &&base) : bz_strm(ENCODE, std::move(base)) {};
};
class lzma_strm : public cpr_stream {
@@ -199,8 +199,8 @@ protected:
ENCODE_LZMA
} mode;
- lzma_strm(mode_t mode, sFILE &&fp)
- : cpr_stream(std::move(fp)), mode(mode), strm(LZMA_STREAM_INIT) {
+ lzma_strm(mode_t mode, stream_ptr &&base)
+ : cpr_stream(std::move(base)), mode(mode), strm(LZMA_STREAM_INIT) {
lzma_options_lzma opt;
// Initialize preset
@@ -247,22 +247,22 @@ private:
class lzma_decoder : public lzma_strm {
public:
- explicit lzma_decoder(sFILE &&fp) : lzma_strm(DECODE, std::move(fp)) {}
+ explicit lzma_decoder(stream_ptr &&base) : lzma_strm(DECODE, std::move(base)) {}
};
class xz_encoder : public lzma_strm {
public:
- explicit xz_encoder(sFILE &&fp) : lzma_strm(ENCODE_XZ, std::move(fp)) {}
+ explicit xz_encoder(stream_ptr &&base) : lzma_strm(ENCODE_XZ, std::move(base)) {}
};
class lzma_encoder : public lzma_strm {
public:
- explicit lzma_encoder(sFILE &&fp) : lzma_strm(ENCODE_LZMA, std::move(fp)) {}
+ explicit lzma_encoder(stream_ptr &&base) : lzma_strm(ENCODE_LZMA, std::move(base)) {}
};
class LZ4F_decoder : public cpr_stream {
public:
- explicit LZ4F_decoder(sFILE &&fp) : cpr_stream(std::move(fp)), outbuf(nullptr) {
+ explicit LZ4F_decoder(stream_ptr &&base) : cpr_stream(std::move(base)), outbuf(nullptr) {
LZ4F_createDecompressionContext(&ctx, LZ4F_VERSION);
}
@@ -317,8 +317,8 @@ private:
class LZ4F_encoder : public cpr_stream {
public:
- explicit LZ4F_encoder(sFILE &&fp)
- : cpr_stream(std::move(fp)), outbuf(nullptr), outCapacity(0) {
+ explicit LZ4F_encoder(stream_ptr &&base)
+ : cpr_stream(std::move(base)), outbuf(nullptr), outCapacity(0) {
LZ4F_createCompressionContext(&ctx, LZ4F_VERSION);
}
@@ -378,8 +378,8 @@ private:
class LZ4_decoder : public cpr_stream {
public:
- explicit LZ4_decoder(sFILE &&fp)
- : cpr_stream(std::move(fp)), out_buf(new char[LZ4_UNCOMPRESSED]),
+ explicit LZ4_decoder(stream_ptr &&base)
+ : cpr_stream(std::move(base)), out_buf(new char[LZ4_UNCOMPRESSED]),
buffer(new char[LZ4_COMPRESSED]), init(false), block_sz(0), buf_off(0) {}
~LZ4_decoder() override {
@@ -439,8 +439,8 @@ private:
class LZ4_encoder : public cpr_stream {
public:
- explicit LZ4_encoder(sFILE &&fp)
- : cpr_stream(std::move(fp)), outbuf(new char[LZ4_COMPRESSED]), buf(new char[LZ4_UNCOMPRESSED]),
+ explicit LZ4_encoder(stream_ptr &&base)
+ : cpr_stream(std::move(base)), outbuf(new char[LZ4_COMPRESSED]), buf(new char[LZ4_UNCOMPRESSED]),
init(false), buf_off(0), in_total(0) {}
int write(const void *in, size_t size) override {
@@ -500,38 +500,38 @@ private:
unsigned in_total;
};
-stream_ptr get_encoder(format_t type, sFILE &&fp) {
+stream_ptr get_encoder(format_t type, stream_ptr &&base) {
switch (type) {
case XZ:
- return make_unique(std::move(fp));
+ return make_unique(std::move(base));
case LZMA:
- return make_unique(std::move(fp));
+ return make_unique(std::move(base));
case BZIP2:
- return make_unique(std::move(fp));
+ return make_unique(std::move(base));
case LZ4:
- return make_unique(std::move(fp));
+ return make_unique(std::move(base));
case LZ4_LEGACY:
- return make_unique(std::move(fp));
+ return make_unique(std::move(base));
case GZIP:
default:
- return make_unique(std::move(fp));
+ return make_unique(std::move(base));
}
}
-stream_ptr get_decoder(format_t type, sFILE &&fp) {
+stream_ptr get_decoder(format_t type, stream_ptr &&base) {
switch (type) {
case XZ:
case LZMA:
- return make_unique(std::move(fp));
+ return make_unique(std::move(base));
case BZIP2:
- return make_unique(std::move(fp));
+ return make_unique(std::move(base));
case LZ4:
- return make_unique(std::move(fp));
+ return make_unique(std::move(base));
case LZ4_LEGACY:
- return make_unique(std::move(fp));
+ return make_unique(std::move(base));
case GZIP:
default:
- return make_unique(std::move(fp));
+ return make_unique(std::move(base));
}
}
@@ -573,7 +573,7 @@ void decompress(char *infile, const char *outfile) {
}
FILE *out_fp = outfile == "-"sv ? stdout : xfopen(outfile, "we");
- strm = get_decoder(type, make_sFILE(out_fp));
+ strm = get_decoder(type, make_unique(out_fp));
if (ext) *ext = '.';
}
if (strm->write(buf, len) < 0)
@@ -614,7 +614,7 @@ void compress(const char *method, const char *infile, const char *outfile) {
out_fp = outfile == "-"sv ? stdout : xfopen(outfile, "we");
}
- auto strm = get_encoder(it->second, make_sFILE(out_fp));
+ auto strm = get_encoder(it->second, make_unique(out_fp));
char buf[4096];
size_t len;
diff --git a/native/jni/magiskboot/compress.h b/native/jni/magiskboot/compress.h
index bb162455f..7a8ab9c23 100644
--- a/native/jni/magiskboot/compress.h
+++ b/native/jni/magiskboot/compress.h
@@ -4,9 +4,9 @@
#include "format.h"
-stream_ptr get_encoder(format_t type, sFILE &&fp);
+stream_ptr get_encoder(format_t type, stream_ptr &&base);
-stream_ptr get_decoder(format_t type, sFILE &&fp);
+stream_ptr get_decoder(format_t type, stream_ptr &&base);
void compress(const char *method, const char *infile, const char *outfile);
diff --git a/native/jni/magiskboot/ramdisk.cpp b/native/jni/magiskboot/ramdisk.cpp
index 798292409..67a65e7da 100644
--- a/native/jni/magiskboot/ramdisk.cpp
+++ b/native/jni/magiskboot/ramdisk.cpp
@@ -244,7 +244,7 @@ void magisk_cpio::compress() {
uint8_t *data;
size_t len;
- auto strm = make_stream(get_encoder(XZ, make_stream(data, len)));
+ auto strm = make_stream_fp(get_encoder(XZ, make_unique(data, len)));
dump(strm.release());
entries.clear();
@@ -264,7 +264,7 @@ void magisk_cpio::decompress() {
char *data;
size_t len;
{
- auto strm = get_decoder(XZ, make_stream(data, len));
+ auto strm = get_decoder(XZ, make_unique(data, len));
strm->write(it->second->data, it->second->filesize);
}
diff --git a/native/jni/magiskhide/hide_utils.cpp b/native/jni/magiskhide/hide_utils.cpp
index c08a8eacc..b451fa386 100644
--- a/native/jni/magiskhide/hide_utils.cpp
+++ b/native/jni/magiskhide/hide_utils.cpp
@@ -183,7 +183,7 @@ bool init_list() {
// Migrate old hide list into database
if (access(LEGACY_LIST, R_OK) == 0) {
- file_readline(LEGACY_LIST, [](string_view s) -> bool {
+ file_readline(true, LEGACY_LIST, [](string_view s) -> bool {
add_list(s.data());
return true;
});
diff --git a/native/jni/magiskpolicy/policydb.cpp b/native/jni/magiskpolicy/policydb.cpp
index 2ffaacfad..6c775b1c2 100644
--- a/native/jni/magiskpolicy/policydb.cpp
+++ b/native/jni/magiskpolicy/policydb.cpp
@@ -178,7 +178,7 @@ int dump_policydb(const char *file) {
size_t len;
{
- auto fp = make_stream(data, len);
+ auto fp = make_stream_fp(data, len);
struct policy_file pf;
policy_file_init(&pf);
pf.type = PF_USE_STDIO;
diff --git a/native/jni/magiskpolicy/statement.cpp b/native/jni/magiskpolicy/statement.cpp
index bf97ae5e4..43f8b8bff 100644
--- a/native/jni/magiskpolicy/statement.cpp
+++ b/native/jni/magiskpolicy/statement.cpp
@@ -416,10 +416,10 @@ void parse_statement(const char *statement) {
}
void load_rule_file(const char *file) {
- file_readline(file, [](string_view line) -> bool {
+ file_readline(true, file, [](string_view line) -> bool {
if (line.empty() || line[0] == '#')
return true;
parse_statement(line.data());
return true;
- }, true);
+ });
}
diff --git a/native/jni/utils/file.cpp b/native/jni/utils/file.cpp
index 42f8463b5..9af4365b3 100644
--- a/native/jni/utils/file.cpp
+++ b/native/jni/utils/file.cpp
@@ -1,8 +1,4 @@
-/* file.cpp - Contains all files related utilities
- */
-
#include
-#include
#include
#include
#include
@@ -359,7 +355,7 @@ void write_zero(int fd, size_t size) {
}
}
-void file_readline(const char *file, const function &fn, bool trim) {
+void file_readline(bool trim, const char *file, const std::function &fn) {
FILE *fp = xfopen(file, "re");
if (fp == nullptr)
return;
@@ -384,7 +380,7 @@ void file_readline(const char *file, const function &fn, boo
}
void parse_prop_file(const char *file, const function &fn) {
- file_readline(file, [&](string_view line_view) -> bool {
+ file_readline(true, file, [&](string_view line_view) -> bool {
char *line = (char *) line_view.data();
if (line[0] == '#')
return true;
@@ -393,7 +389,7 @@ void parse_prop_file(const char *file, const function &fn) {
diff --git a/native/jni/utils/files.h b/native/jni/utils/files.h
index 26880258b..a53f632c5 100644
--- a/native/jni/utils/files.h
+++ b/native/jni/utils/files.h
@@ -1,17 +1,16 @@
#pragma once
+#include
+#include
#include
#include
#include
+#include "xwrap.h"
+
#define do_align(p, a) (((p) + (a) - 1) / (a) * (a))
#define align_off(p, a) (do_align(p, a) - (p))
-using sFILE = std::unique_ptr;
-static inline sFILE make_sFILE(FILE *fp = nullptr) {
- return sFILE(fp, fclose);
-}
-
struct file_attr {
struct stat st;
char con[128];
@@ -36,12 +35,15 @@ void clone_attr(const char *source, const char *target);
void fd_full_read(int fd, void **buf, size_t *size);
void full_read(const char *filename, void **buf, size_t *size);
void write_zero(int fd, size_t size);
-
-void file_readline(const char *file, const std::function &fn, bool trim = false);
-void parse_prop_file(const char *file, const std::function
- &fn);
+void file_readline(bool trim, const char *file, const std::function &fn);
+static inline void file_readline(const char *file,
+ const std::function &fn) {
+ file_readline(false, file, fn);
+}
+void parse_prop_file(const char *file,
+ const std::function &fn);
void *__mmap(const char *filename, size_t *size, bool rw);
-void frm_rf(int dirfd, std::initializer_list excl = std::initializer_list());
+void frm_rf(int dirfd, std::initializer_list excl = {});
void clone_dir(int src, int dest, bool overwrite = true);
void parse_mnt(const char *file, const std::function &fn);
@@ -80,3 +82,22 @@ void mmap_rw(const char *filename, B &buf, L &sz) {
buf = (B) __mmap(filename, &__sz, true);
sz = __sz;
}
+
+using sFILE = std::unique_ptr;
+using sDIR = std::unique_ptr;
+
+static inline sDIR open_dir(const char *path) {
+ return sDIR(opendir(path), closedir);
+}
+
+static inline sDIR xopen_dir(const char *path) {
+ return sDIR(xopendir(path), closedir);
+}
+
+static inline sFILE open_file(const char *path, const char *mode) {
+ return sFILE(fopen(path, mode), fclose);
+}
+
+static inline sFILE xopen_file(const char *path, const char *mode) {
+ return sFILE(xfopen(path, mode), fclose);
+}
diff --git a/native/jni/utils/include/stream.h b/native/jni/utils/include/stream.h
index a07097fce..4e07dce25 100644
--- a/native/jni/utils/include/stream.h
+++ b/native/jni/utils/include/stream.h
@@ -5,17 +5,6 @@
#include "../files.h"
-class stream;
-
-using stream_ptr = std::unique_ptr;
-
-sFILE make_stream(stream_ptr &&strm);
-
-template
-sFILE make_stream(Args &&... args) {
- return make_stream(stream_ptr(new T(std::forward(args)...)));
-}
-
class stream {
public:
virtual int read(void *buf, size_t len);
@@ -24,35 +13,22 @@ public:
virtual ~stream() = default;
};
-// Delegates all operations to the base FILE pointer
+using stream_ptr = std::unique_ptr;
+
+// Delegates all operations to base stream
class filter_stream : public stream {
public:
- filter_stream(sFILE &&fp = make_sFILE()) : fp(std::move(fp)) {}
+ filter_stream(stream_ptr &&base) : base(std::move(base)) {}
int read(void *buf, size_t len) override;
int write(const void *buf, size_t len) override;
- void set_base(sFILE &&f);
- template
- void set_base(Args&&... args) {
- set_base(make_stream(std::forward(args)...));
- }
-
protected:
- sFILE fp;
-};
-
-// Handy interface for classes that need custom seek logic
-class seekable_stream : public stream {
-protected:
- size_t _pos = 0;
-
- off_t seek_pos(off_t off, int whence);
- virtual size_t end_pos() = 0;
+ stream_ptr base;
};
// Byte stream that dynamically allocates memory
-class byte_stream : public seekable_stream {
+class byte_stream : public stream {
public:
byte_stream(uint8_t *&buf, size_t &len);
template
@@ -64,10 +40,10 @@ public:
private:
uint8_t *&_buf;
size_t &_len;
+ size_t _pos = 0;
size_t _cap = 0;
void resize(size_t new_pos, bool zero = false);
- size_t end_pos() final { return _len; }
};
// File stream but does not close the file descriptor at any time
@@ -81,3 +57,28 @@ public:
private:
int fd;
};
+
+/* ****************************************
+ * Bridge between stream class and C stdio
+ * ****************************************/
+
+// sFILE -> stream_ptr
+class fp_stream final : public stream {
+public:
+ fp_stream(FILE *fp = nullptr) : fp(fp, fclose) {}
+ fp_stream(sFILE &&fp) : fp(std::move(fp)) {}
+ int read(void *buf, size_t len) override;
+ int write(const void *buf, size_t len) override;
+ off_t seek(off_t off, int whence) override;
+
+private:
+ sFILE fp;
+};
+
+// stream_ptr -> sFILE
+sFILE make_stream_fp(stream_ptr &&strm);
+
+template
+sFILE make_stream_fp(Args &&... args) {
+ return make_stream_fp(stream_ptr(new T(std::forward(args)...)));
+}
diff --git a/native/jni/utils/include/utils.h b/native/jni/utils/include/utils.h
index 77638f7d7..e2c71fede 100644
--- a/native/jni/utils/include/utils.h
+++ b/native/jni/utils/include/utils.h
@@ -1,14 +1,5 @@
#pragma once
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
#include "../missing.h"
#include "../xwrap.h"
#include "../files.h"
diff --git a/native/jni/utils/misc.h b/native/jni/utils/misc.h
index e5cd3721b..ac0d51f99 100644
--- a/native/jni/utils/misc.h
+++ b/native/jni/utils/misc.h
@@ -1,5 +1,6 @@
#pragma once
+#include
#include
#include
#include
diff --git a/native/jni/utils/selinux.cpp b/native/jni/utils/selinux.cpp
index f41fd8106..616f1a954 100644
--- a/native/jni/utils/selinux.cpp
+++ b/native/jni/utils/selinux.cpp
@@ -207,11 +207,10 @@ void restore_rootcon() {
setfilecon(MIRRDIR, ROOT_CON);
setfilecon(BLOCKDIR, ROOT_CON);
- struct dirent *entry;
- DIR *dir = xopendir("/sbin");
- int dfd = dirfd(dir);
+ auto dir = xopen_dir("/sbin");
+ int dfd = dirfd(dir.get());
- while ((entry = xreaddir(dir))) {
+ for (dirent *entry; (entry = xreaddir(dir.get()));) {
if (entry->d_name == "."sv || entry->d_name == ".."sv)
continue;
setfilecon_at(dfd, entry->d_name, ROOT_CON);
@@ -220,6 +219,4 @@ void restore_rootcon() {
setfilecon("/sbin/magisk.bin", MAGISK_CON);
setfilecon("/sbin/magisk", MAGISK_CON);
setfilecon("/sbin/magiskinit", MAGISK_CON);
-
- closedir(dir);
}
diff --git a/native/jni/utils/stream.cpp b/native/jni/utils/stream.cpp
index a0b687578..ee80cb0a5 100644
--- a/native/jni/utils/stream.cpp
+++ b/native/jni/utils/stream.cpp
@@ -23,7 +23,7 @@ static int strm_close(void *v) {
return 0;
}
-sFILE make_stream(stream_ptr &&strm) {
+sFILE make_stream_fp(stream_ptr &&strm) {
sFILE fp(funopen(strm.release(), strm_read, strm_write, strm_seek, strm_close), fclose);
setbuf(fp.get(), nullptr);
return fp;
@@ -44,29 +44,24 @@ off_t stream::seek(off_t off, int whence) {
return -1;
}
-int filter_stream::read(void *buf, size_t len) {
+int fp_stream::read(void *buf, size_t len) {
return fread(buf, 1, len, fp.get());
}
-int filter_stream::write(const void *buf, size_t len) {
+int fp_stream::write(const void *buf, size_t len) {
return fwrite(buf, 1, len, fp.get());
}
-void filter_stream::set_base(sFILE &&f) {
- fp = std::move(f);
+off_t fp_stream::seek(off_t off, int whence) {
+ return fseek(fp.get(), off, whence);
}
-off_t seekable_stream::seek_pos(off_t off, int whence) {
- switch (whence) {
- case SEEK_CUR:
- return _pos + off;
- case SEEK_END:
- return end_pos() + off;
- case SEEK_SET:
- return off;
- default:
- return -1;
- }
+int filter_stream::read(void *buf, size_t len) {
+ return base->read(buf, len);
+}
+
+int filter_stream::write(const void *buf, size_t len) {
+ return base->write(buf, len);
}
byte_stream::byte_stream(uint8_t *&buf, size_t &len) : _buf(buf), _len(len) {
@@ -89,9 +84,20 @@ int byte_stream::write(const void *buf, size_t len) {
}
off_t byte_stream::seek(off_t off, int whence) {
- off_t np = seek_pos(off, whence);
- if (np < 0)
- return -1;
+ off_t np;
+ switch (whence) {
+ case SEEK_CUR:
+ np = _pos + off;
+ break;
+ case SEEK_END:
+ np = _len + off;
+ break;
+ case SEEK_SET:
+ np = off;
+ break;
+ default:
+ return -1;
+ }
resize(np, true);
_pos = np;
return np;
diff --git a/native/jni/utils/xwrap.cpp b/native/jni/utils/xwrap.cpp
index 122cef6a9..29a6db369 100644
--- a/native/jni/utils/xwrap.cpp
+++ b/native/jni/utils/xwrap.cpp
@@ -1,17 +1,6 @@
-/* xwrap.cpp - wrappers around existing library functions.
- *
- * Functions with the x prefix are wrappers that either succeed or log the
- * error message. They usually have the same arguments and return value
- * as the function they wrap.
- *
- */
-
#include
-#include
#include
#include
-#include
-#include
#include
#include
#include
diff --git a/native/jni/utils/xwrap.h b/native/jni/utils/xwrap.h
index 106e15b87..ffa4f6536 100644
--- a/native/jni/utils/xwrap.h
+++ b/native/jni/utils/xwrap.h
@@ -1,5 +1,10 @@
#pragma once
+#include
+#include
+#include
+#include
+
FILE *xfopen(const char *pathname, const char *mode);
FILE *xfdopen(int fd, const char *mode);
int xopen(const char *pathname, int flags);