General QoL changes

This commit is contained in:
topjohnwu 2019-12-13 00:37:06 -05:00
parent 8c500709e4
commit af060b3132
22 changed files with 205 additions and 213 deletions

View File

@ -131,7 +131,7 @@ void node_entry::create_module_tree(const char *module) {
auto full_path = get_path(); auto full_path = get_path();
snprintf(buf, PATH_MAX, "%s/%s%s", MODULEROOT, module, full_path.c_str()); snprintf(buf, PATH_MAX, "%s/%s%s", MODULEROOT, module, full_path.c_str());
unique_ptr<DIR, decltype(&closedir)> dir(xopendir(buf), closedir); auto dir = xopen_dir(buf);
if (!dir) if (!dir)
return; return;
@ -148,7 +148,7 @@ void node_entry::create_module_tree(const char *module) {
return; 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) if (entry->d_name == "."sv || entry->d_name == ".."sv)
continue; continue;
// Create new node // Create new node
@ -207,22 +207,18 @@ void node_entry::create_module_tree(const char *module) {
} }
void node_entry::clone_skeleton() { void node_entry::clone_skeleton() {
DIR *dir;
struct dirent *entry;
// Clone the structure // Clone the structure
auto full_path = get_path(); auto full_path = get_path();
snprintf(buf, PATH_MAX, "%s%s", MIRRDIR, full_path.c_str()); snprintf(buf, PATH_MAX, "%s%s", MIRRDIR, full_path.data());
if (!(dir = xopendir(buf))) if (auto dir = xopen_dir(buf); dir) {
return; for (dirent *entry; (entry = xreaddir(dir.get()));) {
while ((entry = xreaddir(dir))) {
if (entry->d_name == "."sv || entry->d_name == ".."sv) if (entry->d_name == "."sv || entry->d_name == ".."sv)
continue; continue;
// Create dummy node // Create dummy node
auto dummy = new node_entry(entry->d_name, entry->d_type, IS_DUMMY); auto dummy = new node_entry(entry->d_name, entry->d_type, IS_DUMMY);
insert(dummy); insert(dummy);
} }
closedir(dir); } else { return; }
if (status & IS_SKEL) { if (status & IS_SKEL) {
file_attr attr; file_attr attr;
@ -460,9 +456,8 @@ void remove_modules() {
LOGI("* Remove all modules and reboot"); LOGI("* Remove all modules and reboot");
chdir(MODULEROOT); chdir(MODULEROOT);
rm_rf("lost+found"); rm_rf("lost+found");
DIR *dir = xopendir("."); auto dir = xopen_dir(".");
struct dirent *entry; for (dirent *entry; (entry = xreaddir(dir.get()));) {
while ((entry = xreaddir(dir))) {
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;
@ -471,7 +466,6 @@ void remove_modules() {
chdir(".."); chdir("..");
} }
} }
closedir(dir);
chdir("/"); chdir("/");
reboot(); reboot();
} }
@ -479,9 +473,8 @@ void remove_modules() {
static void collect_modules() { static void collect_modules() {
chdir(MODULEROOT); chdir(MODULEROOT);
rm_rf("lost+found"); rm_rf("lost+found");
DIR *dir = xopendir("."); auto dir = xopen_dir(".");
struct dirent *entry; for (dirent *entry; (entry = xreaddir(dir.get()));) {
while ((entry = xreaddir(dir))) {
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;
@ -501,7 +494,6 @@ static void collect_modules() {
chdir(".."); chdir("..");
} }
} }
closedir(dir);
chdir("/"); chdir("/");
} }
@ -575,15 +567,14 @@ static bool check_data() {
} }
void unlock_blocks() { void unlock_blocks() {
DIR *dir;
struct dirent *entry;
int fd, dev, OFF = 0; int fd, dev, OFF = 0;
if (!(dir = xopendir("/dev/block"))) auto dir = xopen_dir("/dev/block");
if (!dir)
return; 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 (entry->d_type == DT_BLK) {
if ((fd = openat(dev, entry->d_name, O_RDONLY | O_CLOEXEC)) < 0) if ((fd = openat(dev, entry->d_name, O_RDONLY | O_CLOEXEC)) < 0)
continue; continue;
@ -592,7 +583,6 @@ void unlock_blocks() {
close(fd); close(fd);
} }
} }
closedir(dir);
} }
static bool log_dump = false; static bool log_dump = false;

View File

@ -118,10 +118,10 @@ static void main_daemon() {
// Unmount pre-init patches // Unmount pre-init patches
if (access(ROOTMNT, F_OK) == 0) { if (access(ROOTMNT, F_OK) == 0) {
file_readline(ROOTMNT, [](auto line) -> bool { file_readline(true, ROOTMNT, [](auto line) -> bool {
umount2(line.data(), MNT_DETACH); umount2(line.data(), MNT_DETACH);
return true; return true;
}, true); });
} }
LOGI(SHOW_VER(Magisk) " daemon started\n"); LOGI(SHOW_VER(Magisk) " daemon started\n");

View File

@ -26,15 +26,14 @@ 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];
DIR *dir;
struct dirent *entry;
sprintf(path, SECURE_DIR "/%s.d", stage); sprintf(path, SECURE_DIR "/%s.d", stage);
if (!(dir = xopendir(path))) auto dir = xopen_dir(path);
if (!dir)
return; return;
chdir(path); chdir(path);
bool pfs = strcmp(stage, "post-fs-data") == 0; bool pfs = stage == "post-fs-data"sv;
while ((entry = xreaddir(dir))) { 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 (access(entry->d_name, X_OK) == -1)
continue; continue;
@ -50,13 +49,12 @@ void exec_common_script(const char *stage) {
} }
} }
closedir(dir);
chdir("/"); 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) {
char path[4096]; char path[4096];
bool pfs = strcmp(stage, "post-fs-data") == 0; bool pfs = stage == "post-fs-data"sv;
for (auto &m : module_list) { for (auto &m : module_list) {
const char* module = m.c_str(); const char* module = m.c_str();
sprintf(path, MODULEROOT "/%s/%s.sh", module, stage); sprintf(path, MODULEROOT "/%s/%s.sh", module, stage);

View File

@ -197,10 +197,10 @@ int main(int argc, char *argv[]) {
return test_main(argc, argv); return test_main(argc, argv);
#endif #endif
if (argc > 1 && strcmp(argv[1], "-x") == 0) { if (argc > 1 && argv[1] == "-x"sv) {
if (strcmp(argv[2], "magisk") == 0) if (argv[2] == "magisk"sv)
return dump_magisk(argv[3], 0755); 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); return dump_manager(argv[3], 0644);
} }
@ -208,15 +208,15 @@ int main(int argc, char *argv[]) {
return 1; return 1;
setup_klog(); setup_klog();
if (argc > 1 && argv[1] == "selinux_setup"sv) { unique_ptr<BaseInit> init;
auto init = make_unique<SecondStageInit>(argv);
init->start();
}
cmdline cmd{}; cmdline cmd{};
if (argc > 1 && argv[1] == "selinux_setup"sv) {
init = make_unique<SecondStageInit>(argv);
} else {
// This will also mount /sys and /proc
load_kernel_info(&cmd); load_kernel_info(&cmd);
unique_ptr<BaseInit> init;
if (cmd.force_normal_boot) { if (cmd.force_normal_boot) {
init = make_unique<ABFirstStageInit>(argv, &cmd); init = make_unique<ABFirstStageInit>(argv, &cmd);
} else if (cmd.skip_initramfs) { } else if (cmd.skip_initramfs) {
@ -230,6 +230,7 @@ int main(int argc, char *argv[]) {
else else
init = make_unique<RootFSInit>(argv, &cmd); init = make_unique<RootFSInit>(argv, &cmd);
} }
}
// Run the main routine // Run the main routine
init->start(); init->start();

View File

@ -44,17 +44,15 @@ static void parse_device(devinfo *dev, const char *uevent) {
static void collect_devices() { static void collect_devices() {
char path[128]; char path[128];
devinfo dev{}; devinfo dev{};
DIR *dir = xopendir("/sys/dev/block"); if (auto dir = xopen_dir("/sys/dev/block"); dir) {
if (dir == nullptr) for (dirent *entry; (entry = readdir(dir.get()));) {
return;
for (dirent *entry; (entry = readdir(dir));) {
if (entry->d_name == "."sv || entry->d_name == ".."sv) if (entry->d_name == "."sv || entry->d_name == ".."sv)
continue; continue;
sprintf(path, "/sys/dev/block/%s/uevent", entry->d_name); sprintf(path, "/sys/dev/block/%s/uevent", entry->d_name);
parse_device(&dev, path); parse_device(&dev, path);
dev_list.push_back(dev); dev_list.push_back(dev);
} }
closedir(dir); }
} }
static int64_t setup_block(bool write_block = true) { static int64_t setup_block(bool write_block = true) {

View File

@ -426,17 +426,16 @@ static void patch_fstab(const string &fstab) {
#define FSR "/first_stage_ramdisk" #define FSR "/first_stage_ramdisk"
void ABFirstStageInit::prepare() { void ABFirstStageInit::prepare() {
DIR *dir = xopendir(FSR); auto dir = xopen_dir(FSR);
if (!dir) if (!dir)
return; return;
string fstab(FSR "/"); string fstab(FSR "/");
for (dirent *de; (de = readdir(dir));) { for (dirent *de; (de = xreaddir(dir.get()));) {
if (strstr(de->d_name, "fstab")) { if (strstr(de->d_name, "fstab")) {
fstab += de->d_name; fstab += de->d_name;
break; break;
} }
} }
closedir(dir);
if (fstab.length() == sizeof(FSR)) if (fstab.length() == sizeof(FSR))
return; return;
@ -453,14 +452,13 @@ void ABFirstStageInit::prepare() {
} }
void AFirstStageInit::prepare() { void AFirstStageInit::prepare() {
DIR *dir = xopendir("/"); auto dir = xopen_dir("/");
for (dirent *de; (de = readdir(dir));) { for (dirent *de; (de = xreaddir(dir.get()));) {
if (strstr(de->d_name, "fstab")) { if (strstr(de->d_name, "fstab")) {
patch_fstab(de->d_name); patch_fstab(de->d_name);
break; break;
} }
} }
closedir(dir);
// Move stuffs for next stage // Move stuffs for next stage
xmkdir("/system", 0755); xmkdir("/system", 0755);

View File

@ -22,14 +22,14 @@ uint32_t dyn_img_hdr::j32 = 0;
uint64_t dyn_img_hdr::j64 = 0; uint64_t dyn_img_hdr::j64 = 0;
static void decompress(format_t type, int fd, const void *in, size_t size) { static void decompress(format_t type, int fd, const void *in, size_t size) {
auto ptr = get_decoder(type, make_stream<fd_stream>(fd)); auto ptr = get_decoder(type, make_unique<fd_stream>(fd));
ptr->write(in, size); ptr->write(in, size);
} }
static off_t compress(format_t type, int fd, const void *in, size_t size) { static off_t compress(format_t type, int fd, const void *in, size_t size) {
auto prev = lseek(fd, 0, SEEK_CUR); auto prev = lseek(fd, 0, SEEK_CUR);
{ {
auto strm = get_encoder(type, make_stream<fd_stream>(fd)); auto strm = get_encoder(type, make_unique<fd_stream>(fd));
strm->write(in, size); strm->write(in, size);
} }
auto now = lseek(fd, 0, SEEK_CUR); auto now = lseek(fd, 0, SEEK_CUR);

View File

@ -57,7 +57,7 @@ protected:
ENCODE ENCODE
} mode; } 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) { switch(mode) {
case DECODE: case DECODE:
inflateInit2(&strm, 15 | 16); inflateInit2(&strm, 15 | 16);
@ -99,12 +99,12 @@ private:
class gz_decoder : public gz_strm { class gz_decoder : public gz_strm {
public: 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 { class gz_encoder : public gz_strm {
public: 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 { class bz_strm : public cpr_stream {
@ -131,7 +131,7 @@ protected:
ENCODE ENCODE
} mode; } 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) { switch(mode) {
case DECODE: case DECODE:
BZ2_bzDecompressInit(&strm, 0, 0); BZ2_bzDecompressInit(&strm, 0, 0);
@ -173,12 +173,12 @@ private:
class bz_decoder : public bz_strm { class bz_decoder : public bz_strm {
public: 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 { class bz_encoder : public bz_strm {
public: 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 { class lzma_strm : public cpr_stream {
@ -199,8 +199,8 @@ protected:
ENCODE_LZMA ENCODE_LZMA
} mode; } mode;
lzma_strm(mode_t mode, sFILE &&fp) lzma_strm(mode_t mode, stream_ptr &&base)
: cpr_stream(std::move(fp)), mode(mode), strm(LZMA_STREAM_INIT) { : cpr_stream(std::move(base)), mode(mode), strm(LZMA_STREAM_INIT) {
lzma_options_lzma opt; lzma_options_lzma opt;
// Initialize preset // Initialize preset
@ -247,22 +247,22 @@ private:
class lzma_decoder : public lzma_strm { class lzma_decoder : public lzma_strm {
public: 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 { class xz_encoder : public lzma_strm {
public: 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 { class lzma_encoder : public lzma_strm {
public: 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 { class LZ4F_decoder : public cpr_stream {
public: 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); LZ4F_createDecompressionContext(&ctx, LZ4F_VERSION);
} }
@ -317,8 +317,8 @@ private:
class LZ4F_encoder : public cpr_stream { class LZ4F_encoder : public cpr_stream {
public: public:
explicit LZ4F_encoder(sFILE &&fp) explicit LZ4F_encoder(stream_ptr &&base)
: cpr_stream(std::move(fp)), outbuf(nullptr), outCapacity(0) { : cpr_stream(std::move(base)), outbuf(nullptr), outCapacity(0) {
LZ4F_createCompressionContext(&ctx, LZ4F_VERSION); LZ4F_createCompressionContext(&ctx, LZ4F_VERSION);
} }
@ -378,8 +378,8 @@ private:
class LZ4_decoder : public cpr_stream { class LZ4_decoder : public cpr_stream {
public: public:
explicit LZ4_decoder(sFILE &&fp) explicit LZ4_decoder(stream_ptr &&base)
: cpr_stream(std::move(fp)), out_buf(new char[LZ4_UNCOMPRESSED]), : cpr_stream(std::move(base)), out_buf(new char[LZ4_UNCOMPRESSED]),
buffer(new char[LZ4_COMPRESSED]), init(false), block_sz(0), buf_off(0) {} buffer(new char[LZ4_COMPRESSED]), init(false), block_sz(0), buf_off(0) {}
~LZ4_decoder() override { ~LZ4_decoder() override {
@ -439,8 +439,8 @@ private:
class LZ4_encoder : public cpr_stream { class LZ4_encoder : public cpr_stream {
public: public:
explicit LZ4_encoder(sFILE &&fp) explicit LZ4_encoder(stream_ptr &&base)
: cpr_stream(std::move(fp)), outbuf(new char[LZ4_COMPRESSED]), buf(new char[LZ4_UNCOMPRESSED]), : cpr_stream(std::move(base)), outbuf(new char[LZ4_COMPRESSED]), buf(new char[LZ4_UNCOMPRESSED]),
init(false), buf_off(0), in_total(0) {} init(false), buf_off(0), in_total(0) {}
int write(const void *in, size_t size) override { int write(const void *in, size_t size) override {
@ -500,38 +500,38 @@ private:
unsigned in_total; unsigned in_total;
}; };
stream_ptr get_encoder(format_t type, sFILE &&fp) { stream_ptr get_encoder(format_t type, stream_ptr &&base) {
switch (type) { switch (type) {
case XZ: case XZ:
return make_unique<xz_encoder>(std::move(fp)); return make_unique<xz_encoder>(std::move(base));
case LZMA: case LZMA:
return make_unique<lzma_encoder>(std::move(fp)); return make_unique<lzma_encoder>(std::move(base));
case BZIP2: case BZIP2:
return make_unique<bz_encoder>(std::move(fp)); return make_unique<bz_encoder>(std::move(base));
case LZ4: case LZ4:
return make_unique<LZ4F_encoder>(std::move(fp)); return make_unique<LZ4F_encoder>(std::move(base));
case LZ4_LEGACY: case LZ4_LEGACY:
return make_unique<LZ4_encoder>(std::move(fp)); return make_unique<LZ4_encoder>(std::move(base));
case GZIP: case GZIP:
default: default:
return make_unique<gz_encoder>(std::move(fp)); return make_unique<gz_encoder>(std::move(base));
} }
} }
stream_ptr get_decoder(format_t type, sFILE &&fp) { stream_ptr get_decoder(format_t type, stream_ptr &&base) {
switch (type) { switch (type) {
case XZ: case XZ:
case LZMA: case LZMA:
return make_unique<lzma_decoder>(std::move(fp)); return make_unique<lzma_decoder>(std::move(base));
case BZIP2: case BZIP2:
return make_unique<bz_decoder>(std::move(fp)); return make_unique<bz_decoder>(std::move(base));
case LZ4: case LZ4:
return make_unique<LZ4F_decoder>(std::move(fp)); return make_unique<LZ4F_decoder>(std::move(base));
case LZ4_LEGACY: case LZ4_LEGACY:
return make_unique<LZ4_decoder>(std::move(fp)); return make_unique<LZ4_decoder>(std::move(base));
case GZIP: case GZIP:
default: default:
return make_unique<gz_decoder>(std::move(fp)); return make_unique<gz_decoder>(std::move(base));
} }
} }
@ -573,7 +573,7 @@ void decompress(char *infile, const char *outfile) {
} }
FILE *out_fp = outfile == "-"sv ? stdout : xfopen(outfile, "we"); FILE *out_fp = outfile == "-"sv ? stdout : xfopen(outfile, "we");
strm = get_decoder(type, make_sFILE(out_fp)); strm = get_decoder(type, make_unique<fp_stream>(out_fp));
if (ext) *ext = '.'; if (ext) *ext = '.';
} }
if (strm->write(buf, len) < 0) 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"); 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<fp_stream>(out_fp));
char buf[4096]; char buf[4096];
size_t len; size_t len;

View File

@ -4,9 +4,9 @@
#include "format.h" #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); void compress(const char *method, const char *infile, const char *outfile);

View File

@ -244,7 +244,7 @@ void magisk_cpio::compress() {
uint8_t *data; uint8_t *data;
size_t len; size_t len;
auto strm = make_stream(get_encoder(XZ, make_stream<byte_stream>(data, len))); auto strm = make_stream_fp(get_encoder(XZ, make_unique<byte_stream>(data, len)));
dump(strm.release()); dump(strm.release());
entries.clear(); entries.clear();
@ -264,7 +264,7 @@ void magisk_cpio::decompress() {
char *data; char *data;
size_t len; size_t len;
{ {
auto strm = get_decoder(XZ, make_stream<byte_stream>(data, len)); auto strm = get_decoder(XZ, make_unique<byte_stream>(data, len));
strm->write(it->second->data, it->second->filesize); strm->write(it->second->data, it->second->filesize);
} }

View File

@ -183,7 +183,7 @@ bool init_list() {
// Migrate old hide list into database // Migrate old hide list into database
if (access(LEGACY_LIST, R_OK) == 0) { 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()); add_list(s.data());
return true; return true;
}); });

View File

@ -178,7 +178,7 @@ int dump_policydb(const char *file) {
size_t len; size_t len;
{ {
auto fp = make_stream<byte_stream>(data, len); auto fp = make_stream_fp<byte_stream>(data, len);
struct policy_file pf; struct policy_file pf;
policy_file_init(&pf); policy_file_init(&pf);
pf.type = PF_USE_STDIO; pf.type = PF_USE_STDIO;

View File

@ -416,10 +416,10 @@ void parse_statement(const char *statement) {
} }
void load_rule_file(const char *file) { 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] == '#') if (line.empty() || line[0] == '#')
return true; return true;
parse_statement(line.data()); parse_statement(line.data());
return true; return true;
}, true); });
} }

View File

@ -1,8 +1,4 @@
/* file.cpp - Contains all files related utilities
*/
#include <sys/sendfile.h> #include <sys/sendfile.h>
#include <sys/mman.h>
#include <linux/fs.h> #include <linux/fs.h>
#include <stdlib.h> #include <stdlib.h>
#include <fcntl.h> #include <fcntl.h>
@ -359,7 +355,7 @@ void write_zero(int fd, size_t size) {
} }
} }
void file_readline(const char *file, const function<bool (string_view)> &fn, bool trim) { void file_readline(bool trim, const char *file, const std::function<bool(std::string_view)> &fn) {
FILE *fp = xfopen(file, "re"); FILE *fp = xfopen(file, "re");
if (fp == nullptr) if (fp == nullptr)
return; return;
@ -384,7 +380,7 @@ void file_readline(const char *file, const function<bool (string_view)> &fn, boo
} }
void parse_prop_file(const char *file, const function<bool (string_view, string_view)> &fn) { void parse_prop_file(const char *file, const function<bool (string_view, string_view)> &fn) {
file_readline(file, [&](string_view line_view) -> bool { file_readline(true, file, [&](string_view line_view) -> bool {
char *line = (char *) line_view.data(); char *line = (char *) line_view.data();
if (line[0] == '#') if (line[0] == '#')
return true; return true;
@ -393,7 +389,7 @@ void parse_prop_file(const char *file, const function<bool (string_view, string_
return true; return true;
*eql = '\0'; *eql = '\0';
return fn(line, eql + 1); return fn(line, eql + 1);
}, true); });
} }
void parse_mnt(const char *file, const function<bool (mntent*)> &fn) { void parse_mnt(const char *file, const function<bool (mntent*)> &fn) {

View File

@ -1,17 +1,16 @@
#pragma once #pragma once
#include <sys/mman.h>
#include <sys/stat.h>
#include <mntent.h> #include <mntent.h>
#include <functional> #include <functional>
#include <string_view> #include <string_view>
#include "xwrap.h"
#define do_align(p, a) (((p) + (a) - 1) / (a) * (a)) #define do_align(p, a) (((p) + (a) - 1) / (a) * (a))
#define align_off(p, a) (do_align(p, a) - (p)) #define align_off(p, a) (do_align(p, a) - (p))
using sFILE = std::unique_ptr<FILE, decltype(&fclose)>;
static inline sFILE make_sFILE(FILE *fp = nullptr) {
return sFILE(fp, fclose);
}
struct file_attr { struct file_attr {
struct stat st; struct stat st;
char con[128]; 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 fd_full_read(int fd, void **buf, size_t *size);
void full_read(const char *filename, 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 write_zero(int fd, size_t size);
void file_readline(bool trim, const char *file, const std::function<bool(std::string_view)> &fn);
void file_readline(const char *file, const std::function<bool (std::string_view)> &fn, bool trim = false); static inline void file_readline(const char *file,
void parse_prop_file(const char *file, const std::function const std::function<bool(std::string_view)> &fn) {
<bool(std::string_view, std::string_view)> &fn); file_readline(false, file, fn);
}
void parse_prop_file(const char *file,
const std::function<bool(std::string_view, std::string_view)> &fn);
void *__mmap(const char *filename, size_t *size, bool rw); void *__mmap(const char *filename, size_t *size, bool rw);
void frm_rf(int dirfd, std::initializer_list<const char *> excl = std::initializer_list<const char *>()); void frm_rf(int dirfd, std::initializer_list<const char *> excl = {});
void clone_dir(int src, int dest, bool overwrite = true); void clone_dir(int src, int dest, bool overwrite = true);
void parse_mnt(const char *file, const std::function<bool(mntent*)> &fn); void parse_mnt(const char *file, const std::function<bool(mntent*)> &fn);
@ -80,3 +82,22 @@ void mmap_rw(const char *filename, B &buf, L &sz) {
buf = (B) __mmap(filename, &__sz, true); buf = (B) __mmap(filename, &__sz, true);
sz = __sz; sz = __sz;
} }
using sFILE = std::unique_ptr<FILE, decltype(&fclose)>;
using sDIR = std::unique_ptr<DIR, decltype(&closedir)>;
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);
}

View File

@ -5,17 +5,6 @@
#include "../files.h" #include "../files.h"
class stream;
using stream_ptr = std::unique_ptr<stream>;
sFILE make_stream(stream_ptr &&strm);
template <class T, class... Args>
sFILE make_stream(Args &&... args) {
return make_stream(stream_ptr(new T(std::forward<Args>(args)...)));
}
class stream { class stream {
public: public:
virtual int read(void *buf, size_t len); virtual int read(void *buf, size_t len);
@ -24,35 +13,22 @@ public:
virtual ~stream() = default; virtual ~stream() = default;
}; };
// Delegates all operations to the base FILE pointer using stream_ptr = std::unique_ptr<stream>;
// Delegates all operations to base stream
class filter_stream : public stream { class filter_stream : public stream {
public: 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 read(void *buf, size_t len) override;
int write(const void *buf, size_t len) override; int write(const void *buf, size_t len) override;
void set_base(sFILE &&f);
template <class T, class... Args >
void set_base(Args&&... args) {
set_base(make_stream<T>(std::forward<Args>(args)...));
}
protected: protected:
sFILE fp; stream_ptr base;
};
// 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;
}; };
// Byte stream that dynamically allocates memory // Byte stream that dynamically allocates memory
class byte_stream : public seekable_stream { class byte_stream : public stream {
public: public:
byte_stream(uint8_t *&buf, size_t &len); byte_stream(uint8_t *&buf, size_t &len);
template <class byte> template <class byte>
@ -64,10 +40,10 @@ public:
private: private:
uint8_t *&_buf; uint8_t *&_buf;
size_t &_len; size_t &_len;
size_t _pos = 0;
size_t _cap = 0; size_t _cap = 0;
void resize(size_t new_pos, bool zero = false); 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 // File stream but does not close the file descriptor at any time
@ -81,3 +57,28 @@ public:
private: private:
int fd; 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 <class T, class... Args>
sFILE make_stream_fp(Args &&... args) {
return make_stream_fp(stream_ptr(new T(std::forward<Args>(args)...)));
}

View File

@ -1,14 +1,5 @@
#pragma once #pragma once
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <stdio.h>
#include <dirent.h>
#include <pthread.h>
#include <poll.h>
#include <mntent.h>
#include "../missing.h" #include "../missing.h"
#include "../xwrap.h" #include "../xwrap.h"
#include "../files.h" #include "../files.h"

View File

@ -1,5 +1,6 @@
#pragma once #pragma once
#include <pthread.h>
#include <string> #include <string>
#include <functional> #include <functional>
#include <string_view> #include <string_view>

View File

@ -207,11 +207,10 @@ void restore_rootcon() {
setfilecon(MIRRDIR, ROOT_CON); setfilecon(MIRRDIR, ROOT_CON);
setfilecon(BLOCKDIR, ROOT_CON); setfilecon(BLOCKDIR, ROOT_CON);
struct dirent *entry; auto dir = xopen_dir("/sbin");
DIR *dir = xopendir("/sbin"); int dfd = dirfd(dir.get());
int dfd = dirfd(dir);
while ((entry = xreaddir(dir))) { for (dirent *entry; (entry = xreaddir(dir.get()));) {
if (entry->d_name == "."sv || entry->d_name == ".."sv) if (entry->d_name == "."sv || entry->d_name == ".."sv)
continue; continue;
setfilecon_at(dfd, entry->d_name, ROOT_CON); setfilecon_at(dfd, entry->d_name, ROOT_CON);
@ -220,6 +219,4 @@ void restore_rootcon() {
setfilecon("/sbin/magisk.bin", MAGISK_CON); setfilecon("/sbin/magisk.bin", MAGISK_CON);
setfilecon("/sbin/magisk", MAGISK_CON); setfilecon("/sbin/magisk", MAGISK_CON);
setfilecon("/sbin/magiskinit", MAGISK_CON); setfilecon("/sbin/magiskinit", MAGISK_CON);
closedir(dir);
} }

View File

@ -23,7 +23,7 @@ static int strm_close(void *v) {
return 0; 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); sFILE fp(funopen(strm.release(), strm_read, strm_write, strm_seek, strm_close), fclose);
setbuf(fp.get(), nullptr); setbuf(fp.get(), nullptr);
return fp; return fp;
@ -44,29 +44,24 @@ off_t stream::seek(off_t off, int whence) {
return -1; 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()); 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()); return fwrite(buf, 1, len, fp.get());
} }
void filter_stream::set_base(sFILE &&f) { off_t fp_stream::seek(off_t off, int whence) {
fp = std::move(f); return fseek(fp.get(), off, whence);
} }
off_t seekable_stream::seek_pos(off_t off, int whence) { int filter_stream::read(void *buf, size_t len) {
switch (whence) { return base->read(buf, len);
case SEEK_CUR: }
return _pos + off;
case SEEK_END: int filter_stream::write(const void *buf, size_t len) {
return end_pos() + off; return base->write(buf, len);
case SEEK_SET:
return off;
default:
return -1;
}
} }
byte_stream::byte_stream(uint8_t *&buf, size_t &len) : _buf(buf), _len(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 byte_stream::seek(off_t off, int whence) {
off_t np = seek_pos(off, whence); off_t np;
if (np < 0) 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; return -1;
}
resize(np, true); resize(np, true);
_pos = np; _pos = np;
return np; return np;

View File

@ -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 <sched.h> #include <sched.h>
#include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h> #include <unistd.h>
#include <fcntl.h>
#include <dirent.h>
#include <errno.h> #include <errno.h>
#include <pthread.h> #include <pthread.h>
#include <sys/socket.h> #include <sys/socket.h>

View File

@ -1,5 +1,10 @@
#pragma once #pragma once
#include <dirent.h>
#include <stdio.h>
#include <poll.h>
#include <fcntl.h>
FILE *xfopen(const char *pathname, const char *mode); FILE *xfopen(const char *pathname, const char *mode);
FILE *xfdopen(int fd, const char *mode); FILE *xfdopen(int fd, const char *mode);
int xopen(const char *pathname, int flags); int xopen(const char *pathname, int flags);