Integrate MagiskHide into Magisk Daemon
This commit is contained in:
parent
054a1e5ea4
commit
144ff5e716
@ -37,7 +37,7 @@ LOCAL_SRC_FILES := \
|
||||
# su/utils.c \
|
||||
# su/pts.c
|
||||
|
||||
LOCAL_CFLAGS := -Wno-implicit-exception-spec-mismatch
|
||||
LOCAL_CFLAGS := -Wno-implicit-exception-spec-mismatch -DDEBUG
|
||||
LOCAL_LDLIBS := -llog
|
||||
|
||||
include $(BUILD_EXECUTABLE)
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <sys/un.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
@ -18,12 +19,33 @@
|
||||
#include "daemon.h"
|
||||
|
||||
static void request_handler(int client) {
|
||||
/* TODO: Put all function entrypoints here
|
||||
it'll currently just log the input string */
|
||||
char *s = read_string(client);
|
||||
client_request req = read_int(client);
|
||||
char *s;
|
||||
int pid, status, code;
|
||||
switch (req) {
|
||||
case LAUNCH_MAGISKHIDE:
|
||||
launch_magiskhide(client);
|
||||
break;
|
||||
case STOP_MAGISKHIDE:
|
||||
stop_magiskhide(client);
|
||||
break;
|
||||
case ADD_HIDELIST:
|
||||
// TODO: Add hidelist
|
||||
break;
|
||||
case RM_HIDELIST:
|
||||
// TODO: Remove hidelist
|
||||
break;
|
||||
case SUPERUSER:
|
||||
// TODO: Run su
|
||||
break;
|
||||
case TEST:
|
||||
s = read_string(client);
|
||||
LOGI("%s\n", s);
|
||||
free(s);
|
||||
write_int(client, 0);
|
||||
break;
|
||||
}
|
||||
close(client);
|
||||
LOGI("%s\n", s);
|
||||
free(s);
|
||||
}
|
||||
|
||||
/* Setup the address and return socket fd */
|
||||
@ -39,10 +61,14 @@ static int setup_socket(struct sockaddr_un *sun) {
|
||||
return fd;
|
||||
}
|
||||
|
||||
|
||||
static void do_nothing() {}
|
||||
|
||||
void start_daemon() {
|
||||
// Launch the daemon, create new session, set proper context
|
||||
if (getuid() != AID_ROOT || getgid() != AID_ROOT) {
|
||||
PLOGE("daemon requires root. uid/gid not root");
|
||||
fprintf(stderr, "Starting daemon requires root: %s\n", strerror(errno));
|
||||
PLOGE("start daemon");
|
||||
}
|
||||
switch (fork()) {
|
||||
case -1:
|
||||
@ -63,6 +89,12 @@ void start_daemon() {
|
||||
|
||||
// Change process name
|
||||
strcpy(argv0, "magisk_daemon");
|
||||
// The root daemon should not do anything if an error occurs
|
||||
// It should stay intact in any circumstances
|
||||
err_handler = do_nothing;
|
||||
|
||||
// Start log monitor
|
||||
monitor_logs();
|
||||
|
||||
// Loop forever to listen to requests
|
||||
while(1) {
|
||||
|
@ -1,7 +1,24 @@
|
||||
/* daemon.h - Utility functions for daemon-client communication
|
||||
*/
|
||||
|
||||
|
||||
// Commands require connecting to daemon
|
||||
typedef enum {
|
||||
LAUNCH_MAGISKHIDE,
|
||||
STOP_MAGISKHIDE,
|
||||
ADD_HIDELIST,
|
||||
RM_HIDELIST,
|
||||
SUPERUSER,
|
||||
TEST
|
||||
} client_request;
|
||||
|
||||
// daemon.c
|
||||
|
||||
void start_daemon();
|
||||
int connect_daemon();
|
||||
|
||||
// socket_trans.c
|
||||
|
||||
int recv_fd(int sockfd);
|
||||
void send_fd(int sockfd, int fd);
|
||||
int read_int(int fd);
|
||||
|
23
jni/magisk.h
23
jni/magisk.h
@ -9,6 +9,7 @@
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <pthread.h>
|
||||
#include <android/log.h>
|
||||
|
||||
#define AID_SHELL (get_shell_uid())
|
||||
@ -21,6 +22,13 @@
|
||||
|
||||
#define LOG_TAG "Magisk"
|
||||
|
||||
// Global handler for PLOGE
|
||||
extern __thread void (*err_handler)(void);
|
||||
|
||||
// Two common error handlers
|
||||
void exit_proc();
|
||||
void exit_thread();
|
||||
|
||||
#ifdef DEBUG
|
||||
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
|
||||
#else
|
||||
@ -30,14 +38,14 @@
|
||||
#define LOGW(...) __android_log_print(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__)
|
||||
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
|
||||
|
||||
#define PLOGE(fmt, args...) LOGE(fmt " failed with %d: %s", ##args, errno, strerror(errno)); exit(1)
|
||||
#define PLOGEV(fmt, err, args...) LOGE(fmt " failed with %d: %s", ##args, err, strerror(err)); exit(1)
|
||||
#define PLOGE(fmt, args...) LOGE(fmt " failed with %d: %s", ##args, errno, strerror(errno)); err_handler()
|
||||
|
||||
void stub(const char *fmt, ...);
|
||||
|
||||
// Global buffer (only for main thread!!)
|
||||
#define BUF_SIZE 4096
|
||||
extern char magiskbuf[BUF_SIZE];
|
||||
|
||||
extern char *argv0; /* For changing process name */
|
||||
|
||||
// Multi-call entrypoints
|
||||
@ -53,19 +61,12 @@ int resetprop_main(int argc, char *argv[]);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*****************
|
||||
* Magisk Daemon *
|
||||
*****************/
|
||||
|
||||
void start_daemon();
|
||||
int connect_daemon();
|
||||
|
||||
/**************
|
||||
* MagiskHide *
|
||||
**************/
|
||||
|
||||
void launch_magiskhide();
|
||||
void stop_magiskhide();
|
||||
void launch_magiskhide(int client);
|
||||
void stop_magiskhide(int client);
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -18,7 +18,7 @@
|
||||
#include "utils.h"
|
||||
#include "magiskhide.h"
|
||||
|
||||
static int isMocked = 0;
|
||||
static int isMocked = 0, pid;
|
||||
|
||||
static void manage_selinux() {
|
||||
if (isMocked) return;
|
||||
@ -43,23 +43,36 @@ static void lazy_unmount(const char* mountpoint) {
|
||||
LOGI("hide_daemon: Unmount Failed (%s)\n", mountpoint);
|
||||
}
|
||||
|
||||
void hide_daemon() {
|
||||
static void hide_daemon_err() {
|
||||
LOGD("hide_daemon: error occured, stopping magiskhide services\n");
|
||||
// Resume process if possible
|
||||
kill(pid, SIGCONT);
|
||||
int err = 1;
|
||||
write(sv[1], &err, sizeof(err));
|
||||
_exit(-1);
|
||||
}
|
||||
|
||||
int hide_daemon() {
|
||||
// Fork to a new process
|
||||
switch(fork()) {
|
||||
hide_pid = fork();
|
||||
switch(hide_pid) {
|
||||
case -1:
|
||||
PLOGE("fork");
|
||||
return 1;
|
||||
case 0:
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
close(pipefd[1]);
|
||||
close(sv[0]);
|
||||
|
||||
// Set the process name
|
||||
strcpy(argv0, "magiskhide_daemon");
|
||||
// When an error occurs, report its failure to main process
|
||||
err_handler = hide_daemon_err;
|
||||
|
||||
int pid, fd;
|
||||
int fd;
|
||||
FILE *fp;
|
||||
char cache_block[256], *line;
|
||||
struct vector mount_list;
|
||||
@ -67,9 +80,12 @@ void hide_daemon() {
|
||||
cache_block[0] = '\0';
|
||||
|
||||
while(1) {
|
||||
xxread(pipefd[0], &pid, sizeof(pid));
|
||||
xxread(sv[1], &pid, sizeof(pid));
|
||||
// Termination called
|
||||
if(pid == -1) exit(0);
|
||||
if(pid == -1) {
|
||||
LOGD("hide_daemon: received termination request\n");
|
||||
_exit(0);
|
||||
}
|
||||
|
||||
snprintf(magiskbuf, BUF_SIZE, "/proc/%d/ns/mnt", pid);
|
||||
if(access(magiskbuf, F_OK) == -1) continue; // Maybe process died..
|
||||
@ -95,7 +111,7 @@ void hide_daemon() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// First unmount the dummy skeletons, cache mounts, and /sbin links
|
||||
vec_for_each_r(&mount_list, line) {
|
||||
if (strstr(line, "tmpfs /system") || strstr(line, "tmpfs /vendor") || strstr(line, "tmpfs /sbin")
|
||||
@ -125,6 +141,10 @@ void hide_daemon() {
|
||||
|
||||
// All done, send resume signal
|
||||
kill(pid, SIGCONT);
|
||||
|
||||
// Tell main process all is well
|
||||
pid = 0;
|
||||
xwrite(sv[1], &pid, sizeof(pid));
|
||||
}
|
||||
|
||||
// Should never go here
|
||||
|
@ -8,38 +8,67 @@
|
||||
#include <unistd.h>
|
||||
#include <pthread.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "magisk.h"
|
||||
#include "utils.h"
|
||||
#include "magiskhide.h"
|
||||
#include "daemon.h"
|
||||
|
||||
int pipefd[2];
|
||||
int sv[2], hide_pid;
|
||||
struct vector *hide_list, *new_list;
|
||||
|
||||
int isEnabled = 0;
|
||||
static pthread_t proc_monitor_thread;
|
||||
|
||||
static void kill_proc(int pid) {
|
||||
void kill_proc(int pid) {
|
||||
kill(pid, SIGTERM);
|
||||
}
|
||||
|
||||
void launch_magiskhide() {
|
||||
static void usage(char *arg0) {
|
||||
fprintf(stderr,
|
||||
"%s [--options [arguments...] ]\n\n"
|
||||
"Options:\n"
|
||||
" --enable: Start the magiskhide daemon\n"
|
||||
" --disable: Stop the magiskhide daemon\n"
|
||||
" --add <process name>: Add <process name> to the list\n"
|
||||
" --rm <process name>: Remove <process name> from the list\n"
|
||||
" --ls: Print out the current hide list\n"
|
||||
, arg0);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void launch_magiskhide(int client) {
|
||||
if (isEnabled) {
|
||||
write_int(client, 0);
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* The setns system call do not support multithread processes
|
||||
* We have to fork a new process, and communicate with pipe
|
||||
*/
|
||||
|
||||
xpipe(pipefd);
|
||||
LOGI("* Starting MagiskHide\n");
|
||||
|
||||
if (socketpair(AF_LOCAL, SOCK_STREAM, 0, sv) == -1)
|
||||
goto error;
|
||||
|
||||
// Launch the hide daemon
|
||||
hide_daemon();
|
||||
if (hide_daemon())
|
||||
goto error;
|
||||
|
||||
close(pipefd[0]);
|
||||
close(sv[1]);
|
||||
|
||||
// Initialize the hide list
|
||||
hide_list = new_list = malloc(sizeof(*hide_list));
|
||||
hide_list = new_list = xmalloc(sizeof(*hide_list));
|
||||
if (hide_list == NULL)
|
||||
goto error;
|
||||
vec_init(hide_list);
|
||||
FILE *fp = xfopen(HIDELIST, "r");
|
||||
if (fp == NULL)
|
||||
goto error;
|
||||
file_to_vector(hide_list, fp);
|
||||
fclose(fp);
|
||||
char *line;
|
||||
@ -49,20 +78,66 @@ void launch_magiskhide() {
|
||||
}
|
||||
|
||||
// Start a new thread to monitor processes
|
||||
pthread_create(&proc_monitor_thread, NULL, proc_monitor, NULL);
|
||||
pthread_join(proc_monitor_thread, NULL);
|
||||
if (xpthread_create(&proc_monitor_thread, NULL, proc_monitor, NULL))
|
||||
goto error;
|
||||
|
||||
isEnabled = 1;
|
||||
write_int(client, 0);
|
||||
return;
|
||||
error:
|
||||
write_int(client, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
void stop_magiskhide() {
|
||||
void stop_magiskhide(int client) {
|
||||
if (!isEnabled)
|
||||
return;
|
||||
|
||||
LOGI("* Stopping MagiskHide\n");
|
||||
|
||||
int kill = -1;
|
||||
// Terminate hide daemon
|
||||
xwrite(pipefd[1], &kill, sizeof(kill));
|
||||
write(sv[0], &kill, sizeof(kill));
|
||||
close(sv[0]);
|
||||
waitpid(hide_pid, NULL, 0);
|
||||
// Stop process monitor
|
||||
pthread_kill(proc_monitor_thread, SIGUSR1);
|
||||
pthread_join(proc_monitor_thread, NULL);
|
||||
|
||||
isEnabled = 0;
|
||||
write_int(client, 0);
|
||||
}
|
||||
|
||||
int magiskhide_main(int argc, char *argv[]) {
|
||||
launch_magiskhide();
|
||||
return 0;
|
||||
if (argc < 2) {
|
||||
usage(argv[0]);
|
||||
}
|
||||
client_request req;
|
||||
if (strcmp(argv[1], "--enable") == 0) {
|
||||
req = LAUNCH_MAGISKHIDE;
|
||||
} else if (strcmp(argv[1], "--disable") == 0) {
|
||||
req = STOP_MAGISKHIDE;
|
||||
} else if (strcmp(argv[1], "--add") == 0 && argc > 2) {
|
||||
req = ADD_HIDELIST;
|
||||
} else if (strcmp(argv[1], "--rm") == 0 && argc > 2) {
|
||||
req = RM_HIDELIST;
|
||||
} else if (strcmp(argv[1], "--ls") == 0) {
|
||||
FILE *fp = xfopen(HIDELIST, "r");
|
||||
while (fgets(magiskbuf, BUF_SIZE, fp)) {
|
||||
printf("%s", magiskbuf);
|
||||
}
|
||||
fclose(fp);
|
||||
return 0;
|
||||
}
|
||||
int fd = connect_daemon();
|
||||
write_int(fd, req);
|
||||
if (req == ADD_HIDELIST || req == RM_HIDELIST) {
|
||||
write_string(fd, argv[2]);
|
||||
}
|
||||
int code = read_int(fd);
|
||||
close(fd);
|
||||
if (code) {
|
||||
fprintf(stderr, "Error occured in MagiskHide daemon\n");
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
@ -6,13 +6,16 @@
|
||||
#define ENFORCE_FILE "/sys/fs/selinux/enforce"
|
||||
#define POLICY_FILE "/sys/fs/selinux/policy"
|
||||
|
||||
// Kill process
|
||||
void kill_proc(int pid);
|
||||
|
||||
// Hide daemon
|
||||
void hide_daemon();
|
||||
int hide_daemon();
|
||||
|
||||
// Process monitor
|
||||
void *proc_monitor(void *args);
|
||||
|
||||
extern int pipefd[2];
|
||||
extern int sv[2], hide_pid, isEnabled;
|
||||
extern struct vector *hide_list, *new_list;
|
||||
|
||||
#endif
|
||||
|
@ -11,15 +11,12 @@
|
||||
#include <signal.h>
|
||||
#include <pthread.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#include "magisk.h"
|
||||
#include "utils.h"
|
||||
#include "magiskhide.h"
|
||||
|
||||
/* WTF... the macro in the NDK pthread.h is broken.... */
|
||||
#define pthread_cleanup_push_fix(routine, arg) \
|
||||
pthread_cleanup_push(routine, arg) } while(0);
|
||||
|
||||
static int zygote_num = 0;
|
||||
static char init_ns[32], zygote_ns[2][32];
|
||||
|
||||
@ -32,15 +29,21 @@ static void read_namespace(const int pid, char* target, const size_t size) {
|
||||
|
||||
// Workaround for the lack of pthread_cancel
|
||||
static void quit_pthread(int sig) {
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
|
||||
static void cleanup_handler(void *arg) {
|
||||
LOGD("proc_monitor: running cleanup\n");
|
||||
char *line;
|
||||
vec_for_each(hide_list, line) {
|
||||
ps_filter_proc_name(line, kill_proc);
|
||||
}
|
||||
vec_deep_destroy(hide_list);
|
||||
vec_deep_destroy(new_list);
|
||||
free(hide_list);
|
||||
free(new_list);
|
||||
if (new_list != hide_list) {
|
||||
vec_deep_destroy(new_list);
|
||||
free(new_list);
|
||||
}
|
||||
hide_list = new_list = NULL;
|
||||
isEnabled = 0;
|
||||
LOGD("proc_monitor: terminating...\n");
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
|
||||
static void store_zygote_ns(int pid) {
|
||||
@ -51,10 +54,21 @@ static void store_zygote_ns(int pid) {
|
||||
++zygote_num;
|
||||
}
|
||||
|
||||
static void proc_monitor_err() {
|
||||
LOGD("proc_monitor: error occured, stopping magiskhide services\n");
|
||||
int kill = -1;
|
||||
// If process monitor dies, kill hide daemon too
|
||||
write(sv[0], &kill, sizeof(kill));
|
||||
close(sv[0]);
|
||||
waitpid(hide_pid, NULL, 0);
|
||||
quit_pthread(SIGUSR1);
|
||||
}
|
||||
|
||||
void *proc_monitor(void *args) {
|
||||
// Register the cancel signal
|
||||
signal(SIGUSR1, quit_pthread);
|
||||
pthread_cleanup_push_fix(cleanup_handler, NULL);
|
||||
// The error handler should only exit the thread, not the whole process
|
||||
err_handler = proc_monitor_err;
|
||||
|
||||
int pid;
|
||||
char buffer[512];
|
||||
@ -106,6 +120,8 @@ void *proc_monitor(void *args) {
|
||||
hide_list = new_list;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
vec_for_each(hide_list, line) {
|
||||
if (strcmp(processName, line) == 0) {
|
||||
read_namespace(pid, buffer, 32);
|
||||
@ -121,13 +137,19 @@ void *proc_monitor(void *args) {
|
||||
if (ret) break;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
// Send pause signal ASAP
|
||||
if (kill(pid, SIGSTOP) == -1) continue;
|
||||
|
||||
LOGI("proc_monitor: %s(PID=%d ns=%s)\n", processName, pid, buffer);
|
||||
|
||||
// Unmount start
|
||||
xwrite(pipefd[1], &pid, sizeof(pid));
|
||||
xwrite(sv[0], &pid, sizeof(pid));
|
||||
|
||||
// Get the hide daemon return code
|
||||
xxread(sv[0], &ret, sizeof(ret));
|
||||
LOGD("proc_monitor: hide daemon response code: %d\n", ret);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -135,10 +157,15 @@ void *proc_monitor(void *args) {
|
||||
vec_deep_destroy(temp);
|
||||
free(temp);
|
||||
}
|
||||
if (ret) {
|
||||
// Wait hide process to kill itself
|
||||
waitpid(hide_pid, NULL, 0);
|
||||
quit_pthread(SIGUSR1);
|
||||
}
|
||||
}
|
||||
|
||||
// Should never be here
|
||||
pclose(p);
|
||||
quit_pthread(SIGUSR1);
|
||||
pthread_exit(NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
20
jni/main.c
20
jni/main.c
@ -1,6 +1,9 @@
|
||||
/* main.c - The entry point, should be multi-call
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include "utils.h"
|
||||
#include "magisk.h"
|
||||
#include "daemon.h"
|
||||
@ -10,8 +13,22 @@ char *argv0;
|
||||
|
||||
void stub(const char *fmt, ...) {}
|
||||
|
||||
// Global error hander function
|
||||
// Should be changed each thread/process
|
||||
__thread void (*err_handler)(void);
|
||||
|
||||
void exit_proc() {
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
void exit_thread() {
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
argv0 = argv[0];
|
||||
// Exit the whole app if error occurs by default
|
||||
err_handler = exit_proc;
|
||||
char * arg = strrchr(argv[0], '/');
|
||||
if (arg) ++arg;
|
||||
if (strcmp(arg, "magisk") == 0) {
|
||||
@ -27,8 +44,9 @@ int main(int argc, char *argv[]) {
|
||||
} else if (strcmp(argv[1], "--test") == 0) {
|
||||
// Temporary testing entry
|
||||
int fd = connect_daemon();
|
||||
write_int(fd, TEST);
|
||||
write_string(fd, argv[2]);
|
||||
return 0;
|
||||
return read_int(fd);
|
||||
} else {
|
||||
// It's calling applets
|
||||
--argc;
|
||||
|
@ -12,8 +12,8 @@
|
||||
#include "utils.h"
|
||||
|
||||
static void *logger_thread(void *args) {
|
||||
rename("/cache/magisk.log", "/cache/last_magisk.log");
|
||||
FILE *logfile = xfopen("/cache/magisk.log", "w");
|
||||
// rename("/cache/magisk.log", "/cache/last_magisk.log");
|
||||
FILE *logfile = xfopen("/cache/magisk_test.log", "w");
|
||||
// Disable buffering
|
||||
setbuf(logfile, NULL);
|
||||
// Start logcat
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <dirent.h>
|
||||
#include <pthread.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
@ -34,6 +35,9 @@ void *xcalloc(size_t nmemb, size_t size);
|
||||
void *xrealloc(void *ptr, size_t size);
|
||||
ssize_t xsendmsg(int sockfd, const struct msghdr *msg, int flags);
|
||||
ssize_t xrecvmsg(int sockfd, struct msghdr *msg, int flags);
|
||||
int xpthread_create(pthread_t *thread, const pthread_attr_t *attr,
|
||||
void *(*start_routine) (void *), void *arg);
|
||||
int xsocketpair(int domain, int type, int protocol, int sv[2]);
|
||||
|
||||
// log_monitor.c
|
||||
|
||||
@ -48,4 +52,4 @@ ssize_t fdreadline(int fd, char *buf, size_t size);
|
||||
void ps(void (*func)(int));
|
||||
void ps_filter_proc_name(const char *filter, void (*func)(int));
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
@ -39,10 +39,11 @@ int xopen(const char *pathname, int flags) {
|
||||
}
|
||||
|
||||
ssize_t xwrite(int fd, const void *buf, size_t count) {
|
||||
if (count != write(fd, buf, count)) {
|
||||
int ret = write(fd, buf, count);
|
||||
if (count != ret) {
|
||||
PLOGE("write");
|
||||
}
|
||||
return count;
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Read error other than EOF
|
||||
@ -56,24 +57,27 @@ ssize_t xread(int fd, void *buf, size_t count) {
|
||||
|
||||
// Read exact same size as count
|
||||
ssize_t xxread(int fd, void *buf, size_t count) {
|
||||
if (count != read(fd, buf, count)) {
|
||||
int ret = read(fd, buf, count);
|
||||
if (count != ret) {
|
||||
PLOGE("read");
|
||||
}
|
||||
return count;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int xpipe(int pipefd[2]) {
|
||||
if (pipe(pipefd) == -1) {
|
||||
int ret = pipe(pipefd);
|
||||
if (ret == -1) {
|
||||
PLOGE("pipe");
|
||||
}
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int xsetns(int fd, int nstype) {
|
||||
if (setns(fd, nstype) == -1) {
|
||||
int ret = setns(fd, nstype);
|
||||
if (ret == -1) {
|
||||
PLOGE("setns");
|
||||
}
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
DIR *xopendir(const char *name) {
|
||||
@ -102,10 +106,11 @@ pid_t xsetsid() {
|
||||
}
|
||||
|
||||
int xsetcon(char *context) {
|
||||
if (setcon(context) == -1) {
|
||||
int ret = setcon(context);
|
||||
if (ret == -1) {
|
||||
PLOGE("setcon: %s", context);
|
||||
}
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int xsocket(int domain, int type, int protocol) {
|
||||
@ -117,24 +122,27 @@ int xsocket(int domain, int type, int protocol) {
|
||||
}
|
||||
|
||||
int xbind(int sockfd, const struct sockaddr *addr, socklen_t addrlen) {
|
||||
if (bind(sockfd, addr, addrlen) == -1) {
|
||||
int ret = bind(sockfd, addr, addrlen);
|
||||
if (ret == -1) {
|
||||
PLOGE("bind");
|
||||
}
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int xconnect(int sockfd, const struct sockaddr *addr, socklen_t addrlen) {
|
||||
if (connect(sockfd, addr, addrlen) == -1) {
|
||||
int ret = connect(sockfd, addr, addrlen);
|
||||
if (ret == -1) {
|
||||
PLOGE("bind");
|
||||
}
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int xlisten(int sockfd, int backlog) {
|
||||
if (listen(sockfd, backlog) == -1) {
|
||||
int ret = listen(sockfd, backlog);
|
||||
if (ret == -1) {
|
||||
PLOGE("listen");
|
||||
}
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int xaccept(int sockfd, struct sockaddr *addr, socklen_t *addrlen) {
|
||||
@ -185,4 +193,21 @@ ssize_t xrecvmsg(int sockfd, struct msghdr *msg, int flags) {
|
||||
return rec;
|
||||
}
|
||||
|
||||
int xpthread_create(pthread_t *thread, const pthread_attr_t *attr,
|
||||
void *(*start_routine) (void *), void *arg) {
|
||||
errno = pthread_create(thread, attr, start_routine, arg);
|
||||
if (errno) {
|
||||
PLOGE("pthread_create");
|
||||
}
|
||||
return errno;
|
||||
}
|
||||
|
||||
int xsocketpair(int domain, int type, int protocol, int sv[2]) {
|
||||
int ret = socketpair(domain, type, protocol, sv);
|
||||
if (ret == -1) {
|
||||
PLOGE("socketpair");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user