mirror of
https://github.com/topjohnwu/Magisk.git
synced 2025-01-04 14:47:39 +00:00
Upgrade libutils to C++
This commit is contained in:
parent
ef6677f43d
commit
6339ba6bfb
@ -9,7 +9,7 @@
|
|||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
||||||
#include "magisk.h"
|
#include "magisk.h"
|
||||||
#include "utils.hpp"
|
#include "utils.h"
|
||||||
#include "resetprop.h"
|
#include "resetprop.h"
|
||||||
#include "magiskhide.h"
|
#include "magiskhide.h"
|
||||||
#include "daemon.h"
|
#include "daemon.h"
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
#include "magisk.h"
|
#include "magisk.h"
|
||||||
#include "daemon.h"
|
#include "daemon.h"
|
||||||
#include "utils.hpp"
|
#include "utils.h"
|
||||||
#include "magiskhide.h"
|
#include "magiskhide.h"
|
||||||
#include "flags.h"
|
#include "flags.h"
|
||||||
|
|
||||||
|
@ -4,13 +4,12 @@ include $(CLEAR_VARS)
|
|||||||
LOCAL_MODULE:= libutils
|
LOCAL_MODULE:= libutils
|
||||||
LOCAL_C_INCLUDES := jni/include $(LIBUTILS)
|
LOCAL_C_INCLUDES := jni/include $(LIBUTILS)
|
||||||
LOCAL_SRC_FILES := \
|
LOCAL_SRC_FILES := \
|
||||||
utils.cpp \
|
file.cpp \
|
||||||
file.c \
|
misc.cpp \
|
||||||
list.c \
|
selinux.cpp \
|
||||||
misc.c \
|
logging.cpp \
|
||||||
|
xwrap.cpp \
|
||||||
vector.c \
|
vector.c \
|
||||||
selinux.c \
|
legacy.c
|
||||||
logging.c \
|
|
||||||
xwrap.c
|
|
||||||
|
|
||||||
include $(BUILD_STATIC_LIBRARY)
|
include $(BUILD_STATIC_LIBRARY)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* file.c - Contains all files related utilities
|
/* file.cpp - Contains all files related utilities
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -15,7 +15,7 @@
|
|||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "selinux.h"
|
#include "selinux.h"
|
||||||
|
|
||||||
const char **excl_list = NULL;
|
const char **excl_list = nullptr;
|
||||||
|
|
||||||
static int is_excl(const char *name) {
|
static int is_excl(const char *name) {
|
||||||
if (excl_list)
|
if (excl_list)
|
||||||
@ -62,7 +62,7 @@ void in_order_walk(int dirfd, void (*callback)(int, struct dirent*)) {
|
|||||||
struct dirent *entry;
|
struct dirent *entry;
|
||||||
int newfd;
|
int newfd;
|
||||||
DIR *dir = fdopendir(dirfd);
|
DIR *dir = fdopendir(dirfd);
|
||||||
if (dir == NULL) return;
|
if (dir == nullptr) return;
|
||||||
|
|
||||||
while ((entry = xreaddir(dir))) {
|
while ((entry = xreaddir(dir))) {
|
||||||
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
|
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
|
||||||
@ -176,7 +176,7 @@ void cp_afc(const char *source, const char *destination) {
|
|||||||
if (S_ISREG(a.st.st_mode)) {
|
if (S_ISREG(a.st.st_mode)) {
|
||||||
src = xopen(source, O_RDONLY);
|
src = xopen(source, O_RDONLY);
|
||||||
dest = xopen(destination, O_WRONLY | O_CREAT | O_TRUNC);
|
dest = xopen(destination, O_WRONLY | O_CREAT | O_TRUNC);
|
||||||
xsendfile(dest, src, NULL, a.st.st_size);
|
xsendfile(dest, src, nullptr, a.st.st_size);
|
||||||
close(src);
|
close(src);
|
||||||
close(dest);
|
close(dest);
|
||||||
} else if (S_ISLNK(a.st.st_mode)) {
|
} else if (S_ISLNK(a.st.st_mode)) {
|
||||||
@ -321,7 +321,7 @@ static void _mmap(int rw, const char *filename, void **buf, size_t *size) {
|
|||||||
ioctl(fd, BLKGETSIZE64, size);
|
ioctl(fd, BLKGETSIZE64, size);
|
||||||
else
|
else
|
||||||
*size = st.st_size;
|
*size = st.st_size;
|
||||||
*buf = *size > 0 ? xmmap(NULL, *size, PROT_READ | (rw ? PROT_WRITE : 0), MAP_SHARED, fd, 0) : NULL;
|
*buf = *size > 0 ? xmmap(nullptr, *size, PROT_READ | (rw ? PROT_WRITE : 0), MAP_SHARED, fd, 0) : nullptr;
|
||||||
close(fd);
|
close(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -344,7 +344,7 @@ 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) {
|
||||||
int fd = xopen(filename, O_RDONLY | O_CLOEXEC);
|
int fd = xopen(filename, O_RDONLY | O_CLOEXEC);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
*buf = NULL;
|
*buf = nullptr;
|
||||||
*size = 0;
|
*size = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -355,7 +355,7 @@ void full_read(const char *filename, void **buf, size_t *size) {
|
|||||||
void full_read_at(int dirfd, const char *filename, void **buf, size_t *size) {
|
void full_read_at(int dirfd, const char *filename, void **buf, size_t *size) {
|
||||||
int fd = xopenat(dirfd, filename, O_RDONLY | O_CLOEXEC);
|
int fd = xopenat(dirfd, filename, O_RDONLY | O_CLOEXEC);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
*buf = NULL;
|
*buf = nullptr;
|
||||||
*size = 0;
|
*size = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -377,7 +377,7 @@ void stream_full_read(int fd, void **buf, size_t *size) {
|
|||||||
cap *= 2;
|
cap *= 2;
|
||||||
*buf = realloc(*buf, cap);
|
*buf = realloc(*buf, cap);
|
||||||
}
|
}
|
||||||
memcpy(*buf + *size, tmp, read);
|
memcpy((uint8_t *) *buf + *size, tmp, read);
|
||||||
*size += read;
|
*size += read;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -387,3 +387,25 @@ void write_zero(int fd, size_t size) {
|
|||||||
ftruncate(fd, pos + size);
|
ftruncate(fd, pos + size);
|
||||||
lseek(fd, pos + size, SEEK_SET);
|
lseek(fd, pos + size, SEEK_SET);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int file_to_array(const char *filename, Array<char *> &arr) {
|
||||||
|
if (access(filename, R_OK) != 0)
|
||||||
|
return 1;
|
||||||
|
char *line = nullptr;
|
||||||
|
size_t len = 0;
|
||||||
|
ssize_t read;
|
||||||
|
|
||||||
|
FILE *fp = xfopen(filename, "r");
|
||||||
|
if (fp == nullptr)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
while ((read = getline(&line, &len, fp)) != -1) {
|
||||||
|
// Remove end newline
|
||||||
|
if (line[read - 1] == '\n')
|
||||||
|
line[read - 1] = '\0';
|
||||||
|
arr.push_back(line);
|
||||||
|
line = nullptr;
|
||||||
|
}
|
||||||
|
fclose(fp);
|
||||||
|
return 0;
|
||||||
|
}
|
@ -1,43 +0,0 @@
|
|||||||
/* list.h - Double link list implementation
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _LIST_H_
|
|
||||||
#define _LIST_H_
|
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
|
|
||||||
struct list_head {
|
|
||||||
struct list_head *next;
|
|
||||||
struct list_head *prev;
|
|
||||||
};
|
|
||||||
|
|
||||||
void init_list_head(struct list_head *head);
|
|
||||||
void list_insert(struct list_head *pos, struct list_head *node);
|
|
||||||
void list_insert_end(struct list_head *head, struct list_head *node);
|
|
||||||
struct list_head *list_pop(struct list_head *pos);
|
|
||||||
struct list_head *list_pop_end(struct list_head *head);
|
|
||||||
|
|
||||||
#define list_entry(pos, type, member) ({ \
|
|
||||||
const typeof( ((type *)0)->member ) *__mptr = (pos); \
|
|
||||||
(type *)( (char *)__mptr - offsetof(type,member) );})
|
|
||||||
|
|
||||||
#define list_for_each(ptr, head, type, member) \
|
|
||||||
ptr = list_entry((head)->next, type, member); \
|
|
||||||
for (struct list_head *__ = (head)->next; __ != (head); __ = __->next, ptr = list_entry(__, type, member))
|
|
||||||
|
|
||||||
#define list_for_each_r(ptr, head, type, member) \
|
|
||||||
ptr = list_entry((head)->prev, type, member); \
|
|
||||||
for (struct list_head *__ = (head)->prev; __ != (head); __ = __->prev, ptr = list_entry(__, type, member))
|
|
||||||
|
|
||||||
#define list_destory(head, type, member, func) ({ \
|
|
||||||
struct list_head *node = head->next; \
|
|
||||||
while(node != head) { \
|
|
||||||
node = node->next; \
|
|
||||||
if (func) func(list_entry(node->prev, line_list, pos)); \
|
|
||||||
free(list_entry(node->prev, line_list, pos)); \
|
|
||||||
} \
|
|
||||||
head->next = head; \
|
|
||||||
head->prev = head; \
|
|
||||||
})
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,6 +1,10 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
extern void (*freecon)(char * con);
|
extern void (*freecon)(char * con);
|
||||||
extern int (*setcon)(const char * con);
|
extern int (*setcon)(const char * con);
|
||||||
extern int (*getfilecon)(const char *path, char ** con);
|
extern int (*getfilecon)(const char *path, char ** con);
|
||||||
@ -10,3 +14,7 @@ extern int (*lsetfilecon)(const char *path, const char * con);
|
|||||||
|
|
||||||
void dload_selinux();
|
void dload_selinux();
|
||||||
void restorecon();
|
void restorecon();
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
@ -12,6 +12,9 @@
|
|||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
// C++ only
|
||||||
|
#include "array.h"
|
||||||
|
int file_to_array(const char* filename, Array<char *> &arr);
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -92,7 +95,6 @@ int exec_command(int err, int *fd, void (*setenv)(struct vector*), const char *a
|
|||||||
int exec_command_sync(char *const argv0, ...);
|
int exec_command_sync(char *const argv0, ...);
|
||||||
int switch_mnt_ns(int pid);
|
int switch_mnt_ns(int pid);
|
||||||
int fork_dont_care();
|
int fork_dont_care();
|
||||||
void wait_till_exists(const char *target);
|
|
||||||
void gen_rand_str(char *buf, int len);
|
void gen_rand_str(char *buf, int len);
|
||||||
int strend(const char *s1, const char *s2);
|
int strend(const char *s1, const char *s2);
|
||||||
|
|
||||||
|
@ -1,6 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "utils.h"
|
|
||||||
#include "array.h"
|
|
||||||
|
|
||||||
int file_to_array(const char* filename, Array<char *> &arr);
|
|
128
native/jni/utils/legacy.c
Normal file
128
native/jni/utils/legacy.c
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
|
||||||
|
#include "utils.h"
|
||||||
|
#include "logging.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
fd == NULL -> Ignore output
|
||||||
|
*fd < 0 -> Open pipe and set *fd to the read end
|
||||||
|
*fd >= 0 -> STDOUT (or STDERR) will be redirected to *fd
|
||||||
|
*setenv -> A callback function which sets up a vector of environment variables
|
||||||
|
*/
|
||||||
|
int exec_array(int err, int *fd, void (*setenv)(struct vector *), char *const *argv) {
|
||||||
|
int pipefd[2], writeEnd = -1;
|
||||||
|
|
||||||
|
if (fd) {
|
||||||
|
if (*fd < 0) {
|
||||||
|
if (xpipe2(pipefd, O_CLOEXEC) == -1)
|
||||||
|
return -1;
|
||||||
|
writeEnd = pipefd[1];
|
||||||
|
} else {
|
||||||
|
writeEnd = *fd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setup environment
|
||||||
|
char **envp;
|
||||||
|
struct vector env;
|
||||||
|
vec_init(&env);
|
||||||
|
if (setenv) {
|
||||||
|
setenv(&env);
|
||||||
|
envp = (char **) vec_entry(&env);
|
||||||
|
} else {
|
||||||
|
extern char **environ;
|
||||||
|
envp = environ;
|
||||||
|
}
|
||||||
|
|
||||||
|
int pid = xfork();
|
||||||
|
if (pid != 0) {
|
||||||
|
if (fd && *fd < 0) {
|
||||||
|
// Give the read end and close write end
|
||||||
|
*fd = pipefd[0];
|
||||||
|
close(pipefd[1]);
|
||||||
|
}
|
||||||
|
vec_deep_destroy(&env);
|
||||||
|
return pid;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fd) {
|
||||||
|
xdup2(writeEnd, STDOUT_FILENO);
|
||||||
|
if (err)
|
||||||
|
xdup2(writeEnd, STDERR_FILENO);
|
||||||
|
}
|
||||||
|
|
||||||
|
environ = envp;
|
||||||
|
execvp(argv[0], argv);
|
||||||
|
PLOGE("execvp %s", argv[0]);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int v_exec_command(int err, int *fd, void (*setenv)(struct vector*), const char *argv0, va_list argv) {
|
||||||
|
// Collect va_list into vector
|
||||||
|
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(&args, strdup(arg));
|
||||||
|
vec_push_back(&args, NULL);
|
||||||
|
int pid = exec_array(err, fd, setenv, (char **) vec_entry(&args));
|
||||||
|
vec_deep_destroy(&args);
|
||||||
|
return pid;
|
||||||
|
}
|
||||||
|
|
||||||
|
int exec_command_sync(char *const argv0, ...) {
|
||||||
|
va_list argv;
|
||||||
|
va_start(argv, argv0);
|
||||||
|
int pid, status;
|
||||||
|
pid = v_exec_command(0, NULL, NULL, argv0, argv);
|
||||||
|
va_end(argv);
|
||||||
|
if (pid < 0)
|
||||||
|
return pid;
|
||||||
|
waitpid(pid, &status, 0);
|
||||||
|
return WEXITSTATUS(status);
|
||||||
|
}
|
||||||
|
|
||||||
|
int exec_command(int err, int *fd, void (*setenv)(struct vector*), const char *argv0, ...) {
|
||||||
|
va_list argv;
|
||||||
|
va_start(argv, argv0);
|
||||||
|
int pid = v_exec_command(err, fd, setenv, argv0, argv);
|
||||||
|
va_end(argv);
|
||||||
|
return pid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* All the string should be freed manually!! */
|
||||||
|
int file_to_vector(const char* filename, struct vector *v) {
|
||||||
|
if (access(filename, R_OK) != 0)
|
||||||
|
return 1;
|
||||||
|
char *line = NULL;
|
||||||
|
size_t len = 0;
|
||||||
|
ssize_t read;
|
||||||
|
|
||||||
|
FILE *fp = xfopen(filename, "r");
|
||||||
|
if (fp == NULL)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
while ((read = getline(&line, &len, fp)) != -1) {
|
||||||
|
// Remove end newline
|
||||||
|
if (line[read - 1] == '\n')
|
||||||
|
line[read - 1] = '\0';
|
||||||
|
vec_push_back(v, line);
|
||||||
|
line = NULL;
|
||||||
|
}
|
||||||
|
fclose(fp);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int vector_to_file(const char *filename, struct vector *v) {
|
||||||
|
FILE *fp = xfopen(filename, "w");
|
||||||
|
if (fp == NULL)
|
||||||
|
return 1;
|
||||||
|
char *line;
|
||||||
|
vec_for_each(v, line) {
|
||||||
|
fprintf(fp, "%s\n", line);
|
||||||
|
}
|
||||||
|
fclose(fp);
|
||||||
|
return 0;
|
||||||
|
}
|
@ -1,39 +0,0 @@
|
|||||||
/* list.h - Double link list implementation
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "list.h"
|
|
||||||
|
|
||||||
void init_list_head(struct list_head *head) {
|
|
||||||
head->next = head;
|
|
||||||
head->prev = head;
|
|
||||||
}
|
|
||||||
|
|
||||||
void list_insert(struct list_head *pos, struct list_head *node) {
|
|
||||||
// First construct our new node
|
|
||||||
node->next = pos->next;
|
|
||||||
node->prev = pos;
|
|
||||||
// Maintain the list
|
|
||||||
pos->next->prev = node;
|
|
||||||
pos->next = node;
|
|
||||||
}
|
|
||||||
|
|
||||||
void list_insert_end(struct list_head *head, struct list_head *node) {
|
|
||||||
list_insert(head->prev, node);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct list_head *list_pop(struct list_head *pos) {
|
|
||||||
struct list_head *ret;
|
|
||||||
ret = pos->prev;
|
|
||||||
// Maintain the list
|
|
||||||
pos->prev->next = pos->next;
|
|
||||||
pos->next->prev = pos->prev;
|
|
||||||
// Remove references
|
|
||||||
pos->next = pos;
|
|
||||||
pos->prev = pos;
|
|
||||||
// Return the previous node in the list
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct list_head *list_pop_end(struct list_head *head) {
|
|
||||||
return list_pop(head->prev);
|
|
||||||
}
|
|
@ -1,23 +1,15 @@
|
|||||||
/* misc.c - Store all functions that are unable to be catagorized clearly
|
/* misc.cpp - Store all functions that are unable to be catagorized clearly
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define _GNU_SOURCE
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdarg.h>
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
#include <signal.h>
|
|
||||||
#include <sched.h>
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <libgen.h>
|
|
||||||
#include <syscall.h>
|
#include <syscall.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/mount.h>
|
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <sys/inotify.h>
|
|
||||||
#include <sys/sysmacros.h>
|
#include <sys/sysmacros.h>
|
||||||
|
|
||||||
#include "logging.h"
|
#include "logging.h"
|
||||||
@ -25,7 +17,7 @@
|
|||||||
|
|
||||||
unsigned get_shell_uid() {
|
unsigned get_shell_uid() {
|
||||||
struct passwd* ppwd = getpwnam("shell");
|
struct passwd* ppwd = getpwnam("shell");
|
||||||
if (NULL == ppwd)
|
if (nullptr == ppwd)
|
||||||
return 2000;
|
return 2000;
|
||||||
|
|
||||||
return ppwd->pw_uid;
|
return ppwd->pw_uid;
|
||||||
@ -33,7 +25,7 @@ unsigned get_shell_uid() {
|
|||||||
|
|
||||||
unsigned get_system_uid() {
|
unsigned get_system_uid() {
|
||||||
struct passwd* ppwd = getpwnam("system");
|
struct passwd* ppwd = getpwnam("system");
|
||||||
if (NULL == ppwd)
|
if (nullptr == ppwd)
|
||||||
return 1000;
|
return 1000;
|
||||||
|
|
||||||
return ppwd->pw_uid;
|
return ppwd->pw_uid;
|
||||||
@ -41,47 +33,12 @@ unsigned get_system_uid() {
|
|||||||
|
|
||||||
unsigned get_radio_uid() {
|
unsigned get_radio_uid() {
|
||||||
struct passwd* ppwd = getpwnam("radio");
|
struct passwd* ppwd = getpwnam("radio");
|
||||||
if (NULL == ppwd)
|
if (nullptr == ppwd)
|
||||||
return 1001;
|
return 1001;
|
||||||
|
|
||||||
return ppwd->pw_uid;
|
return ppwd->pw_uid;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* All the string should be freed manually!! */
|
|
||||||
int file_to_vector(const char* filename, struct vector *v) {
|
|
||||||
if (access(filename, R_OK) != 0)
|
|
||||||
return 1;
|
|
||||||
char *line = NULL;
|
|
||||||
size_t len = 0;
|
|
||||||
ssize_t read;
|
|
||||||
|
|
||||||
FILE *fp = xfopen(filename, "r");
|
|
||||||
if (fp == NULL)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
while ((read = getline(&line, &len, fp)) != -1) {
|
|
||||||
// Remove end newline
|
|
||||||
if (line[read - 1] == '\n')
|
|
||||||
line[read - 1] = '\0';
|
|
||||||
vec_push_back(v, line);
|
|
||||||
line = NULL;
|
|
||||||
}
|
|
||||||
fclose(fp);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int vector_to_file(const char *filename, struct vector *v) {
|
|
||||||
FILE *fp = xfopen(filename, "w");
|
|
||||||
if (fp == NULL)
|
|
||||||
return 1;
|
|
||||||
char *line;
|
|
||||||
vec_for_each(v, line) {
|
|
||||||
fprintf(fp, "%s\n", line);
|
|
||||||
}
|
|
||||||
fclose(fp);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if the string only contains digits */
|
/* Check if the string only contains digits */
|
||||||
int is_num(const char *s) {
|
int is_num(const char *s) {
|
||||||
int len = strlen(s);
|
int len = strlen(s);
|
||||||
@ -110,93 +67,6 @@ ssize_t fdgets(char *buf, const size_t size, int fd) {
|
|||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
fd == NULL -> Ignore output
|
|
||||||
*fd < 0 -> Open pipe and set *fd to the read end
|
|
||||||
*fd >= 0 -> STDOUT (or STDERR) will be redirected to *fd
|
|
||||||
*setenv -> A callback function which sets up a vector of environment variables
|
|
||||||
*/
|
|
||||||
int exec_array(int err, int *fd, void (*setenv)(struct vector *), char *const *argv) {
|
|
||||||
int pipefd[2], writeEnd = -1;
|
|
||||||
|
|
||||||
if (fd) {
|
|
||||||
if (*fd < 0) {
|
|
||||||
if (xpipe2(pipefd, O_CLOEXEC) == -1)
|
|
||||||
return -1;
|
|
||||||
writeEnd = pipefd[1];
|
|
||||||
} else {
|
|
||||||
writeEnd = *fd;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Setup environment
|
|
||||||
char **envp;
|
|
||||||
struct vector env;
|
|
||||||
vec_init(&env);
|
|
||||||
if (setenv) {
|
|
||||||
setenv(&env);
|
|
||||||
envp = (char **) vec_entry(&env);
|
|
||||||
} else {
|
|
||||||
extern char **environ;
|
|
||||||
envp = environ;
|
|
||||||
}
|
|
||||||
|
|
||||||
int pid = xfork();
|
|
||||||
if (pid != 0) {
|
|
||||||
if (fd && *fd < 0) {
|
|
||||||
// Give the read end and close write end
|
|
||||||
*fd = pipefd[0];
|
|
||||||
close(pipefd[1]);
|
|
||||||
}
|
|
||||||
vec_deep_destroy(&env);
|
|
||||||
return pid;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fd) {
|
|
||||||
xdup2(writeEnd, STDOUT_FILENO);
|
|
||||||
if (err)
|
|
||||||
xdup2(writeEnd, STDERR_FILENO);
|
|
||||||
}
|
|
||||||
|
|
||||||
environ = envp;
|
|
||||||
execvp(argv[0], argv);
|
|
||||||
PLOGE("execvp %s", argv[0]);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int v_exec_command(int err, int *fd, void (*setenv)(struct vector*), const char *argv0, va_list argv) {
|
|
||||||
// Collect va_list into vector
|
|
||||||
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(&args, strdup(arg));
|
|
||||||
vec_push_back(&args, NULL);
|
|
||||||
int pid = exec_array(err, fd, setenv, (char **) vec_entry(&args));
|
|
||||||
vec_deep_destroy(&args);
|
|
||||||
return pid;
|
|
||||||
}
|
|
||||||
|
|
||||||
int exec_command_sync(char *const argv0, ...) {
|
|
||||||
va_list argv;
|
|
||||||
va_start(argv, argv0);
|
|
||||||
int pid, status;
|
|
||||||
pid = v_exec_command(0, NULL, NULL, argv0, argv);
|
|
||||||
va_end(argv);
|
|
||||||
if (pid < 0)
|
|
||||||
return pid;
|
|
||||||
waitpid(pid, &status, 0);
|
|
||||||
return WEXITSTATUS(status);
|
|
||||||
}
|
|
||||||
|
|
||||||
int exec_command(int err, int *fd, void (*setenv)(struct vector*), const char *argv0, ...) {
|
|
||||||
va_list argv;
|
|
||||||
va_start(argv, argv0);
|
|
||||||
int pid = v_exec_command(err, fd, setenv, argv0, argv);
|
|
||||||
va_end(argv);
|
|
||||||
return pid;
|
|
||||||
}
|
|
||||||
|
|
||||||
int switch_mnt_ns(int pid) {
|
int switch_mnt_ns(int pid) {
|
||||||
char mnt[32];
|
char mnt[32];
|
||||||
snprintf(mnt, sizeof(mnt), "/proc/%d/ns/mnt", pid);
|
snprintf(mnt, sizeof(mnt), "/proc/%d/ns/mnt", pid);
|
||||||
@ -214,7 +84,7 @@ int switch_mnt_ns(int pid) {
|
|||||||
int fork_dont_care() {
|
int fork_dont_care() {
|
||||||
int pid = xfork();
|
int pid = xfork();
|
||||||
if (pid) {
|
if (pid) {
|
||||||
waitpid(pid, NULL, 0);
|
waitpid(pid, nullptr, 0);
|
||||||
return pid;
|
return pid;
|
||||||
} else if ((pid = xfork())) {
|
} else if ((pid = xfork())) {
|
||||||
exit(0);
|
exit(0);
|
||||||
@ -222,23 +92,6 @@ int fork_dont_care() {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void wait_till_exists(const char *target) {
|
|
||||||
if (access(target, F_OK) == 0)
|
|
||||||
return;
|
|
||||||
int fd = inotify_init();
|
|
||||||
char *dir = dirname(target);
|
|
||||||
char crap[PATH_MAX];
|
|
||||||
inotify_add_watch(fd, dir, IN_CREATE);
|
|
||||||
while (1) {
|
|
||||||
struct inotify_event event;
|
|
||||||
read(fd, &event, sizeof(event));
|
|
||||||
read(fd, crap, event.len);
|
|
||||||
if (access(target, F_OK) == 0)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
close(fd);
|
|
||||||
}
|
|
||||||
|
|
||||||
void gen_rand_str(char *buf, int len) {
|
void gen_rand_str(char *buf, int len) {
|
||||||
const char base[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
const char base[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
||||||
int urandom;
|
int urandom;
|
||||||
@ -278,7 +131,7 @@ ssize_t __getdelim(char **lineptr, size_t *n, int delim, FILE *stream) {
|
|||||||
|
|
||||||
if (!*lineptr) {
|
if (!*lineptr) {
|
||||||
*n = MIN_CHUNK;
|
*n = MIN_CHUNK;
|
||||||
*lineptr = malloc(*n);
|
*lineptr = (char *) malloc(*n);
|
||||||
if (!*lineptr) {
|
if (!*lineptr) {
|
||||||
errno = ENOMEM;
|
errno = ENOMEM;
|
||||||
return -1;
|
return -1;
|
||||||
@ -290,7 +143,7 @@ ssize_t __getdelim(char **lineptr, size_t *n, int delim, FILE *stream) {
|
|||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
int save_errno;
|
int save_errno;
|
||||||
register int c = getc(stream);
|
int c = getc(stream);
|
||||||
|
|
||||||
save_errno = errno;
|
save_errno = errno;
|
||||||
|
|
||||||
@ -301,7 +154,7 @@ ssize_t __getdelim(char **lineptr, size_t *n, int delim, FILE *stream) {
|
|||||||
*n += MIN_CHUNK;
|
*n += MIN_CHUNK;
|
||||||
|
|
||||||
nchars_avail = *n + *lineptr - read_pos;
|
nchars_avail = *n + *lineptr - read_pos;
|
||||||
*lineptr = realloc(*lineptr, *n);
|
*lineptr = (char *) realloc(*lineptr, *n);
|
||||||
if (!*lineptr) {
|
if (!*lineptr) {
|
||||||
errno = ENOMEM;
|
errno = ENOMEM;
|
||||||
return -1;
|
return -1;
|
@ -9,20 +9,18 @@
|
|||||||
#define UNLABEL_CON "u:object_r:unlabeled:s0"
|
#define UNLABEL_CON "u:object_r:unlabeled:s0"
|
||||||
#define SYSTEM_CON "u:object_r:system_file:s0"
|
#define SYSTEM_CON "u:object_r:system_file:s0"
|
||||||
#define ADB_CON "u:object_r:adb_data_file:s0"
|
#define ADB_CON "u:object_r:adb_data_file:s0"
|
||||||
#define MAGISK_CON "u:object_r:"SEPOL_FILE_DOMAIN":s0"
|
#define MAGISK_CON "u:object_r:" SEPOL_FILE_DOMAIN ":s0"
|
||||||
|
|
||||||
// Stub implementations
|
// Stub implementations
|
||||||
|
|
||||||
static char *empty_str = "";
|
static void v_s(char *) {}
|
||||||
|
|
||||||
static void v_s(char *s) {}
|
static int i_s(const char *) { return 0; }
|
||||||
|
|
||||||
static int i_s(const char *s) { return 0; }
|
static int i_ss(const char *, const char *) { return 0; }
|
||||||
|
|
||||||
static int i_ss(const char *s, const char * ss) { return 0; }
|
static int i_ssp(const char *, char ** sp) {
|
||||||
|
*sp = (char *) xcalloc(1, 1);
|
||||||
static int i_ssp(const char *s, char ** sp) {
|
|
||||||
*sp = empty_str;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39,12 +37,12 @@ void dload_selinux() {
|
|||||||
void *handle = dlopen("libselinux.so", RTLD_LAZY);
|
void *handle = dlopen("libselinux.so", RTLD_LAZY);
|
||||||
if (handle == NULL)
|
if (handle == NULL)
|
||||||
return;
|
return;
|
||||||
freecon = dlsym(handle, "freecon");
|
*(void **) &freecon = dlsym(handle, "freecon");
|
||||||
setcon = dlsym(handle, "setcon");
|
*(void **) &setcon = dlsym(handle, "setcon");
|
||||||
getfilecon = dlsym(handle, "getfilecon");
|
*(void **) &getfilecon = dlsym(handle, "getfilecon");
|
||||||
lgetfilecon = dlsym(handle, "lgetfilecon");
|
*(void **) &lgetfilecon = dlsym(handle, "lgetfilecon");
|
||||||
setfilecon = dlsym(handle, "setfilecon");
|
*(void **) &setfilecon = dlsym(handle, "setfilecon");
|
||||||
lsetfilecon = dlsym(handle, "lsetfilecon");
|
*(void **) &lsetfilecon = dlsym(handle, "lsetfilecon");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void restore_syscon(int dirfd) {
|
static void restore_syscon(int dirfd) {
|
@ -1,25 +0,0 @@
|
|||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#include "utils.hpp"
|
|
||||||
|
|
||||||
int file_to_array(const char *filename, Array<char *> &arr) {
|
|
||||||
if (access(filename, R_OK) != 0)
|
|
||||||
return 1;
|
|
||||||
char *line = NULL;
|
|
||||||
size_t len = 0;
|
|
||||||
ssize_t read;
|
|
||||||
|
|
||||||
FILE *fp = xfopen(filename, "r");
|
|
||||||
if (fp == NULL)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
while ((read = getline(&line, &len, fp)) != -1) {
|
|
||||||
// Remove end newline
|
|
||||||
if (line[read - 1] == '\n')
|
|
||||||
line[read - 1] = '\0';
|
|
||||||
arr.push_back(line);
|
|
||||||
line = NULL;
|
|
||||||
}
|
|
||||||
fclose(fp);
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,4 +1,4 @@
|
|||||||
/* xwrap.c - wrappers around existing library functions.
|
/* xwrap.cpp - wrappers around existing library functions.
|
||||||
*
|
*
|
||||||
* Functions with the x prefix are wrappers that either succeed or log the
|
* Functions with the x prefix are wrappers that either succeed or log the
|
||||||
* error message. They usually have the same arguments and return value
|
* error message. They usually have the same arguments and return value
|
||||||
@ -6,7 +6,6 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define _GNU_SOURCE
|
|
||||||
#include <sched.h>
|
#include <sched.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
Loading…
x
Reference in New Issue
Block a user