Upgrade libutils to C++

This commit is contained in:
topjohnwu 2018-11-03 03:06:01 -04:00
parent ef6677f43d
commit 6339ba6bfb
15 changed files with 200 additions and 304 deletions

View File

@ -9,7 +9,7 @@
#include <sys/stat.h>
#include "magisk.h"
#include "utils.hpp"
#include "utils.h"
#include "resetprop.h"
#include "magiskhide.h"
#include "daemon.h"

View File

@ -18,7 +18,7 @@
#include "magisk.h"
#include "daemon.h"
#include "utils.hpp"
#include "utils.h"
#include "magiskhide.h"
#include "flags.h"

View File

@ -4,13 +4,12 @@ include $(CLEAR_VARS)
LOCAL_MODULE:= libutils
LOCAL_C_INCLUDES := jni/include $(LIBUTILS)
LOCAL_SRC_FILES := \
utils.cpp \
file.c \
list.c \
misc.c \
file.cpp \
misc.cpp \
selinux.cpp \
logging.cpp \
xwrap.cpp \
vector.c \
selinux.c \
logging.c \
xwrap.c
legacy.c
include $(BUILD_STATIC_LIBRARY)

View File

@ -1,4 +1,4 @@
/* file.c - Contains all files related utilities
/* file.cpp - Contains all files related utilities
*/
#include <stdlib.h>
@ -15,7 +15,7 @@
#include "utils.h"
#include "selinux.h"
const char **excl_list = NULL;
const char **excl_list = nullptr;
static int is_excl(const char *name) {
if (excl_list)
@ -62,7 +62,7 @@ void in_order_walk(int dirfd, void (*callback)(int, struct dirent*)) {
struct dirent *entry;
int newfd;
DIR *dir = fdopendir(dirfd);
if (dir == NULL) return;
if (dir == nullptr) return;
while ((entry = xreaddir(dir))) {
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)) {
src = xopen(source, O_RDONLY);
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(dest);
} 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);
else
*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);
}
@ -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) {
int fd = xopen(filename, O_RDONLY | O_CLOEXEC);
if (fd < 0) {
*buf = NULL;
*buf = nullptr;
*size = 0;
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) {
int fd = xopenat(dirfd, filename, O_RDONLY | O_CLOEXEC);
if (fd < 0) {
*buf = NULL;
*buf = nullptr;
*size = 0;
return;
}
@ -377,7 +377,7 @@ void stream_full_read(int fd, void **buf, size_t *size) {
cap *= 2;
*buf = realloc(*buf, cap);
}
memcpy(*buf + *size, tmp, read);
memcpy((uint8_t *) *buf + *size, tmp, read);
*size += read;
}
}
@ -387,3 +387,25 @@ void write_zero(int fd, size_t size) {
ftruncate(fd, pos + size);
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;
}

View File

@ -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

View File

@ -1,6 +1,10 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
extern void (*freecon)(char * con);
extern int (*setcon)(const 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 restorecon();
#ifdef __cplusplus
}
#endif

View File

@ -12,6 +12,9 @@
#include <sys/stat.h>
#ifdef __cplusplus
// C++ only
#include "array.h"
int file_to_array(const char* filename, Array<char *> &arr);
extern "C" {
#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 switch_mnt_ns(int pid);
int fork_dont_care();
void wait_till_exists(const char *target);
void gen_rand_str(char *buf, int len);
int strend(const char *s1, const char *s2);

View File

@ -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
View 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;
}

View File

@ -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);
}

View File

@ -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 <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <fcntl.h>
#include <pwd.h>
#include <signal.h>
#include <sched.h>
#include <unistd.h>
#include <libgen.h>
#include <syscall.h>
#include <sys/types.h>
#include <sys/mount.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/inotify.h>
#include <sys/sysmacros.h>
#include "logging.h"
@ -25,7 +17,7 @@
unsigned get_shell_uid() {
struct passwd* ppwd = getpwnam("shell");
if (NULL == ppwd)
if (nullptr == ppwd)
return 2000;
return ppwd->pw_uid;
@ -33,7 +25,7 @@ unsigned get_shell_uid() {
unsigned get_system_uid() {
struct passwd* ppwd = getpwnam("system");
if (NULL == ppwd)
if (nullptr == ppwd)
return 1000;
return ppwd->pw_uid;
@ -41,47 +33,12 @@ unsigned get_system_uid() {
unsigned get_radio_uid() {
struct passwd* ppwd = getpwnam("radio");
if (NULL == ppwd)
if (nullptr == ppwd)
return 1001;
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 */
int is_num(const char *s) {
int len = strlen(s);
@ -110,93 +67,6 @@ ssize_t fdgets(char *buf, const size_t size, int fd) {
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) {
char mnt[32];
snprintf(mnt, sizeof(mnt), "/proc/%d/ns/mnt", pid);
@ -214,7 +84,7 @@ int switch_mnt_ns(int pid) {
int fork_dont_care() {
int pid = xfork();
if (pid) {
waitpid(pid, NULL, 0);
waitpid(pid, nullptr, 0);
return pid;
} else if ((pid = xfork())) {
exit(0);
@ -222,23 +92,6 @@ int fork_dont_care() {
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) {
const char base[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
int urandom;
@ -278,7 +131,7 @@ ssize_t __getdelim(char **lineptr, size_t *n, int delim, FILE *stream) {
if (!*lineptr) {
*n = MIN_CHUNK;
*lineptr = malloc(*n);
*lineptr = (char *) malloc(*n);
if (!*lineptr) {
errno = ENOMEM;
return -1;
@ -290,7 +143,7 @@ ssize_t __getdelim(char **lineptr, size_t *n, int delim, FILE *stream) {
while (1) {
int save_errno;
register int c = getc(stream);
int c = getc(stream);
save_errno = errno;
@ -301,7 +154,7 @@ ssize_t __getdelim(char **lineptr, size_t *n, int delim, FILE *stream) {
*n += MIN_CHUNK;
nchars_avail = *n + *lineptr - read_pos;
*lineptr = realloc(*lineptr, *n);
*lineptr = (char *) realloc(*lineptr, *n);
if (!*lineptr) {
errno = ENOMEM;
return -1;

View File

@ -9,20 +9,18 @@
#define UNLABEL_CON "u:object_r:unlabeled:s0"
#define SYSTEM_CON "u:object_r:system_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
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 *s, char ** sp) {
*sp = empty_str;
static int i_ssp(const char *, char ** sp) {
*sp = (char *) xcalloc(1, 1);
return 0;
}
@ -39,12 +37,12 @@ void dload_selinux() {
void *handle = dlopen("libselinux.so", RTLD_LAZY);
if (handle == NULL)
return;
freecon = dlsym(handle, "freecon");
setcon = dlsym(handle, "setcon");
getfilecon = dlsym(handle, "getfilecon");
lgetfilecon = dlsym(handle, "lgetfilecon");
setfilecon = dlsym(handle, "setfilecon");
lsetfilecon = dlsym(handle, "lsetfilecon");
*(void **) &freecon = dlsym(handle, "freecon");
*(void **) &setcon = dlsym(handle, "setcon");
*(void **) &getfilecon = dlsym(handle, "getfilecon");
*(void **) &lgetfilecon = dlsym(handle, "lgetfilecon");
*(void **) &setfilecon = dlsym(handle, "setfilecon");
*(void **) &lsetfilecon = dlsym(handle, "lsetfilecon");
}
static void restore_syscon(int dirfd) {

View File

@ -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;
}

View File

@ -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
* error message. They usually have the same arguments and return value
@ -6,7 +6,6 @@
*
*/
#define _GNU_SOURCE
#include <sched.h>
#include <stdio.h>
#include <stdlib.h>