Cleanup and add more xwraps

This commit is contained in:
topjohnwu 2017-10-14 00:08:12 +08:00
parent cddeaffada
commit 594a67fe28
7 changed files with 107 additions and 79 deletions

View File

@ -145,7 +145,7 @@ static void exec_common_script(const char* stage) {
struct dirent *entry; struct dirent *entry;
snprintf(buf, PATH_MAX, "%s/%s.d", COREDIR, stage); snprintf(buf, PATH_MAX, "%s/%s.d", COREDIR, stage);
if (!(dir = opendir(buf))) if (!(dir = xopendir(buf)))
return; return;
while ((entry = xreaddir(dir))) { while ((entry = xreaddir(dir))) {
@ -190,7 +190,7 @@ static void construct_tree(const char *module, struct node_entry *parent) {
char *parent_path = get_full_path(parent); char *parent_path = get_full_path(parent);
snprintf(buf, PATH_MAX, "%s/%s%s", MOUNTPOINT, module, parent_path); snprintf(buf, PATH_MAX, "%s/%s%s", MOUNTPOINT, module, parent_path);
if (!(dir = opendir(buf))) if (!(dir = xopendir(buf)))
goto cleanup; goto cleanup;
while ((entry = xreaddir(dir))) { while ((entry = xreaddir(dir))) {
@ -258,7 +258,7 @@ static void clone_skeleton(struct node_entry *node) {
// Clone the structure // Clone the structure
char *full_path = get_full_path(node); char *full_path = get_full_path(node);
snprintf(buf, PATH_MAX, "%s%s", MIRRDIR, full_path); snprintf(buf, PATH_MAX, "%s%s", MIRRDIR, full_path);
if (!(dir = opendir(buf))) if (!(dir = xopendir(buf)))
goto cleanup; goto cleanup;
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)
@ -278,7 +278,7 @@ static void clone_skeleton(struct node_entry *node) {
xstat(full_path, &s); xstat(full_path, &s);
getfilecon(full_path, &con); getfilecon(full_path, &con);
LOGI("tmpfs: %s\n", full_path); LOGI("tmpfs: %s\n", full_path);
mount("tmpfs", full_path, "tmpfs", 0, NULL); xmount("tmpfs", full_path, "tmpfs", 0, NULL);
chmod(full_path, s.st_mode & 0777); chmod(full_path, s.st_mode & 0777);
chown(full_path, s.st_uid, s.st_gid); chown(full_path, s.st_uid, s.st_gid);
setfilecon(full_path, con); setfilecon(full_path, con);
@ -405,11 +405,11 @@ static void daemon_init() {
// Setup links under /sbin // Setup links under /sbin
xmount(NULL, "/", NULL, MS_REMOUNT, NULL); xmount(NULL, "/", NULL, MS_REMOUNT, NULL);
xmkdir("/root", 0755); xmkdir("/root", 0755);
xchmod("/root", 0755); chmod("/root", 0755);
root = xopen("/root", O_RDONLY | O_CLOEXEC); root = xopen("/root", O_RDONLY | O_CLOEXEC);
sbin = xopen("/sbin", O_RDONLY | O_CLOEXEC); sbin = xopen("/sbin", O_RDONLY | O_CLOEXEC);
dir = fdopendir(sbin); dir = xfdopendir(sbin);
while((entry = readdir(dir))) { while((entry = xreaddir(dir))) {
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) continue; if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) continue;
linkat(sbin, entry->d_name, root, entry->d_name, 0); linkat(sbin, entry->d_name, root, entry->d_name, 0);
if (strcmp(entry->d_name, "magisk") == 0) if (strcmp(entry->d_name, "magisk") == 0)
@ -420,16 +420,16 @@ static void daemon_init() {
sbin = xopen("/sbin", O_RDONLY | O_CLOEXEC); sbin = xopen("/sbin", O_RDONLY | O_CLOEXEC);
fchmod(sbin, 0755); fchmod(sbin, 0755);
fsetfilecon(sbin, "u:object_r:rootfs:s0"); fsetfilecon(sbin, "u:object_r:rootfs:s0");
dir = fdopendir(root); dir = xfdopendir(root);
while((entry = readdir(dir))) { while((entry = xreaddir(dir))) {
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) continue; if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) continue;
snprintf(target, sizeof(target), "/root/%s", entry->d_name); snprintf(target, sizeof(target), "/root/%s", entry->d_name);
snprintf(linkpath, sizeof(linkpath), "/sbin/%s", entry->d_name); snprintf(linkpath, sizeof(linkpath), "/sbin/%s", entry->d_name);
symlink(target, linkpath); xsymlink(target, linkpath);
} }
for (int i = 0; applet[i]; ++i) { for (int i = 0; applet[i]; ++i) {
snprintf(linkpath, sizeof(linkpath), "/sbin/%s", applet[i]); snprintf(linkpath, sizeof(linkpath), "/sbin/%s", applet[i]);
symlink("/root/magisk", linkpath); xsymlink("/root/magisk", linkpath);
} }
xmkdir("/magisk", 0755); xmkdir("/magisk", 0755);
xmount(NULL, "/", NULL, MS_REMOUNT | MS_RDONLY, NULL); xmount(NULL, "/", NULL, MS_REMOUNT | MS_RDONLY, NULL);
@ -476,20 +476,20 @@ static void daemon_init() {
} }
vec_deep_destroy(&mounts); vec_deep_destroy(&mounts);
if (!seperate_vendor) { if (!seperate_vendor) {
symlink(MIRRDIR "/system/vendor", MIRRDIR "/vendor"); xsymlink(MIRRDIR "/system/vendor", MIRRDIR "/vendor");
#ifdef MAGISK_DEBUG #ifdef MAGISK_DEBUG
LOGI("link: %s -> %s\n", MIRRDIR "/system/vendor", MIRRDIR "/vendor"); LOGI("link: %s -> %s\n", MIRRDIR "/system/vendor", MIRRDIR "/vendor");
#else #else
LOGI("link: %s\n", MIRRDIR "/vendor"); LOGI("link: %s\n", MIRRDIR "/vendor");
#endif #endif
} }
mkdir_p(MIRRDIR "/bin", 0755); xmkdir_p(MIRRDIR "/bin", 0755);
bind_mount(DATABIN, MIRRDIR "/bin"); bind_mount(DATABIN, MIRRDIR "/bin");
LOGI("* Setting up internal busybox"); LOGI("* Setting up internal busybox");
mkdir_p(BBPATH, 0755); xmkdir_p(BBPATH, 0755);
exec_command_sync(MIRRDIR "/bin/busybox", "--install", "-s", BBPATH, NULL); exec_command_sync(MIRRDIR "/bin/busybox", "--install", "-s", BBPATH, NULL);
symlink(MIRRDIR "/bin/busybox", BBPATH "/busybox"); xsymlink(MIRRDIR "/bin/busybox", BBPATH "/busybox");
} }
static int prepare_img() { static int prepare_img() {
@ -569,7 +569,7 @@ void fix_filecon() {
****************/ ****************/
static void unblock_boot_process() { static void unblock_boot_process() {
close(open(UNBLOCKFILE, O_RDONLY | O_CREAT)); close(xopen(UNBLOCKFILE, O_RDONLY | O_CREAT));
pthread_exit(NULL); pthread_exit(NULL);
} }
@ -689,7 +689,7 @@ void post_fs_data(int client) {
if (access(buf, F_OK) == 0) { if (access(buf, F_OK) == 0) {
snprintf(buf2, PATH_MAX, "%s/%s/vendor", MOUNTPOINT, module); snprintf(buf2, PATH_MAX, "%s/%s/vendor", MOUNTPOINT, module);
unlink(buf2); unlink(buf2);
symlink(buf, buf2); xsymlink(buf, buf2);
} }
construct_tree(module, sys_root); construct_tree(module, sys_root);
} }
@ -729,7 +729,6 @@ core_only:
auto_start_magiskhide(); auto_start_magiskhide();
unblock: unblock:
unblock_boot_process(); unblock_boot_process();
} }

View File

@ -155,7 +155,7 @@ void start_daemon() {
dump_policydb(SELINUX_LOAD); dump_policydb(SELINUX_LOAD);
// Continue the larger patch in another thread, we will join later // Continue the larger patch in another thread, we will join later
pthread_create(&sepol_patch, NULL, large_sepol_patch, NULL); xpthread_create(&sepol_patch, NULL, large_sepol_patch, NULL);
struct sockaddr_un sun; struct sockaddr_un sun;
fd = setup_socket(&sun); fd = setup_socket(&sun);
@ -170,7 +170,7 @@ void start_daemon() {
unlock_blocks(); unlock_blocks();
// Notifiy init the daemon is started // Notifiy init the daemon is started
close(open(UNBLOCKFILE, O_RDONLY)); close(xopen(UNBLOCKFILE, O_RDONLY));
// Loop forever to listen for requests // Loop forever to listen for requests
while(1) { while(1) {
@ -187,25 +187,19 @@ void start_daemon() {
int connect_daemon() { int connect_daemon() {
struct sockaddr_un sun; struct sockaddr_un sun;
int fd = setup_socket(&sun); int fd = setup_socket(&sun);
if (connect(fd, (struct sockaddr*) &sun, sizeof(sun))) { if (xconnect(fd, (struct sockaddr*) &sun, sizeof(sun))) {
// If we cannot access the daemon, we start a daemon in the child process if possible // If we cannot access the daemon, we start a daemon in the child process if possible
if (getuid() != UID_ROOT || getgid() != UID_ROOT) { if (getuid() != UID_ROOT || getgid() != UID_ROOT) {
fprintf(stderr, "Starting daemon requires root: %s\n", strerror(errno)); fprintf(stderr, "No daemon is currently running!\n");
PLOGE("start daemon"); exit(1);
} }
switch (fork()) { if (xfork() == 0) {
case -1:
PLOGE("fork");
case 0:
LOGD("client: connect fail, try launching new daemon process\n"); LOGD("client: connect fail, try launching new daemon process\n");
close(fd); close(fd);
xsetsid(); xsetsid();
start_daemon(); start_daemon();
break;
default:
break;
} }
do { do {

View File

@ -24,12 +24,14 @@ FILE *xfdopen(int fd, const char *mode);
#define xopen(...) GET_MACRO(__VA_ARGS__, xopen3, xopen2)(__VA_ARGS__) #define xopen(...) GET_MACRO(__VA_ARGS__, xopen3, xopen2)(__VA_ARGS__)
int xopen2(const char *pathname, int flags); int xopen2(const char *pathname, int flags);
int xopen3(const char *pathname, int flags, mode_t mode); int xopen3(const char *pathname, int flags, mode_t mode);
int xopenat(int dirfd, const char *pathname, int flags);
ssize_t xwrite(int fd, const void *buf, size_t count); ssize_t xwrite(int fd, const void *buf, size_t count);
ssize_t xread(int fd, void *buf, size_t count); ssize_t xread(int fd, void *buf, size_t count);
ssize_t xxread(int fd, void *buf, size_t count); ssize_t xxread(int fd, void *buf, size_t count);
int xpipe2(int pipefd[2], int flags); int xpipe2(int pipefd[2], int flags);
int xsetns(int fd, int nstype); int xsetns(int fd, int nstype);
DIR *xopendir(const char *name); DIR *xopendir(const char *name);
DIR *xfdopendir(int fd);
struct dirent *xreaddir(DIR *dirp); struct dirent *xreaddir(DIR *dirp);
pid_t xsetsid(); pid_t xsetsid();
int xsocket(int domain, int type, int protocol); int xsocket(int domain, int type, int protocol);
@ -49,19 +51,21 @@ int xstat(const char *pathname, struct stat *buf);
int xlstat(const char *pathname, struct stat *buf); int xlstat(const char *pathname, struct stat *buf);
int xdup2(int oldfd, int newfd); int xdup2(int oldfd, int newfd);
ssize_t xreadlink(const char *pathname, char *buf, size_t bufsiz); ssize_t xreadlink(const char *pathname, char *buf, size_t bufsiz);
ssize_t xreadlinkat(int dirfd, const char *pathname, char *buf, size_t bufsiz);
int xsymlink(const char *target, const char *linkpath); int xsymlink(const char *target, const char *linkpath);
int xmount(const char *source, const char *target, int xmount(const char *source, const char *target,
const char *filesystemtype, unsigned long mountflags, const char *filesystemtype, unsigned long mountflags,
const void *data); const void *data);
int xumount(const char *target); int xumount(const char *target);
int xumount2(const char *target, int flags); int xumount2(const char *target, int flags);
int xchmod(const char *pathname, mode_t mode);
int xrename(const char *oldpath, const char *newpath); int xrename(const char *oldpath, const char *newpath);
int xmkdir(const char *pathname, mode_t mode); int xmkdir(const char *pathname, mode_t mode);
int xmkdir_p(const char *pathname, mode_t mode);
int xmkdirat(int dirfd, const char *pathname, mode_t mode);
void *xmmap(void *addr, size_t length, int prot, int flags, void *xmmap(void *addr, size_t length, int prot, int flags,
int fd, off_t offset); int fd, off_t offset);
ssize_t xsendfile(int out_fd, int in_fd, off_t *offset, size_t count); ssize_t xsendfile(int out_fd, int in_fd, off_t *offset, size_t count);
int xmkdir_p(const char *pathname, mode_t mode); pid_t xfork();
// misc.c // misc.c

View File

@ -50,16 +50,16 @@ void rm_rf(const char *path) {
void frm_rf(int dirfd) { void frm_rf(int dirfd) {
struct dirent *entry; struct dirent *entry;
int newfd; int newfd;
DIR *dir = fdopendir(dirfd); DIR *dir = xfdopendir(dirfd);
while ((entry = readdir(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)
continue; continue;
if (is_excl(entry->d_name)) if (is_excl(entry->d_name))
continue; continue;
switch (entry->d_type) { switch (entry->d_type) {
case DT_DIR: case DT_DIR:
newfd = openat(dirfd, entry->d_name, O_RDONLY | O_CLOEXEC); newfd = xopenat(dirfd, entry->d_name, O_RDONLY | O_CLOEXEC);
frm_rf(newfd); frm_rf(newfd);
close(newfd); close(newfd);
unlinkat(dirfd, entry->d_name, AT_REMOVEDIR); unlinkat(dirfd, entry->d_name, AT_REMOVEDIR);
@ -88,7 +88,7 @@ void mv_f(const char *source, const char *destination) {
close(dest); close(dest);
} else{ } else{
getattr(source, &a); getattr(source, &a);
rename(source, destination); xrename(source, destination);
setattr(destination, &a); setattr(destination, &a);
} }
rmdir(source); rmdir(source);
@ -101,8 +101,8 @@ void mv_dir(int src, int dest) {
int newsrc, newdest; int newsrc, newdest;
struct file_attr a; struct file_attr a;
dir = fdopendir(src); dir = xfdopendir(src);
while ((entry = readdir(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)
continue; continue;
if (is_excl(entry->d_name)) if (is_excl(entry->d_name))
@ -110,9 +110,9 @@ void mv_dir(int src, int dest) {
getattrat(src, entry->d_name, &a); getattrat(src, entry->d_name, &a);
switch (entry->d_type) { switch (entry->d_type) {
case DT_DIR: case DT_DIR:
mkdirat(dest, entry->d_name, a.st.st_mode & 0777); xmkdirat(dest, entry->d_name, a.st.st_mode & 0777);
newsrc = openat(src, entry->d_name, O_RDONLY | O_CLOEXEC); newsrc = xopenat(src, entry->d_name, O_RDONLY | O_CLOEXEC);
newdest = openat(dest, entry->d_name, O_RDONLY | O_CLOEXEC); newdest = xopenat(dest, entry->d_name, O_RDONLY | O_CLOEXEC);
fsetattr(newdest, &a); fsetattr(newdest, &a);
mv_dir(newsrc, newdest); mv_dir(newsrc, newdest);
close(newsrc); close(newsrc);
@ -164,11 +164,10 @@ void clone_dir(int src, int dest) {
DIR *dir; DIR *dir;
int srcfd, destfd, newsrc, newdest; int srcfd, destfd, newsrc, newdest;
char buf[PATH_MAX]; char buf[PATH_MAX];
ssize_t size;
struct file_attr a; struct file_attr a;
dir = fdopendir(src); dir = xfdopendir(src);
while ((entry = readdir(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)
continue; continue;
if (is_excl(entry->d_name)) if (is_excl(entry->d_name))
@ -176,25 +175,24 @@ void clone_dir(int src, int dest) {
getattrat(src, entry->d_name, &a); getattrat(src, entry->d_name, &a);
switch (entry->d_type) { switch (entry->d_type) {
case DT_DIR: case DT_DIR:
mkdirat(dest, entry->d_name, a.st.st_mode & 0777); xmkdirat(dest, entry->d_name, a.st.st_mode & 0777);
setattrat(dest, entry->d_name, &a); setattrat(dest, entry->d_name, &a);
newsrc = openat(src, entry->d_name, O_RDONLY | O_CLOEXEC); newsrc = xopenat(src, entry->d_name, O_RDONLY | O_CLOEXEC);
newdest = openat(dest, entry->d_name, O_RDONLY | O_CLOEXEC); newdest = xopenat(dest, entry->d_name, O_RDONLY | O_CLOEXEC);
clone_dir(newsrc, newdest); clone_dir(newsrc, newdest);
close(newsrc); close(newsrc);
close(newdest); close(newdest);
break; break;
case DT_REG: case DT_REG:
destfd = openat(dest, entry->d_name, O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC, a.st.st_mode & 0777); destfd = xopenat(dest, entry->d_name, O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC);
srcfd = openat(src, entry->d_name, O_RDONLY | O_CLOEXEC); srcfd = xopenat(src, entry->d_name, O_RDONLY | O_CLOEXEC);
sendfile(destfd, srcfd, 0, a.st.st_size); xsendfile(destfd, srcfd, 0, a.st.st_size);
fsetattr(destfd, &a); fsetattr(destfd, &a);
close(destfd); close(destfd);
close(srcfd); close(srcfd);
break; break;
case DT_LNK: case DT_LNK:
size = readlinkat(src, entry->d_name, buf, sizeof(buf)); xreadlinkat(src, entry->d_name, buf, sizeof(buf));
buf[size] = '\0';
symlinkat(buf, dest, entry->d_name); symlinkat(buf, dest, entry->d_name);
setattrat(dest, entry->d_name, &a); setattrat(dest, entry->d_name, &a);
break; break;
@ -285,15 +283,15 @@ void restorecon(int dirfd, int force) {
fsetfilecon(dirfd, SYSTEM_CON); fsetfilecon(dirfd, SYSTEM_CON);
freecon(con); freecon(con);
dir = fdopendir(dirfd); dir = xfdopendir(dirfd);
while ((entry = readdir(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)
continue; continue;
if (entry->d_type == DT_DIR) { if (entry->d_type == DT_DIR) {
fd = openat(dirfd, entry->d_name, O_RDONLY | O_CLOEXEC); fd = xopenat(dirfd, entry->d_name, O_RDONLY | O_CLOEXEC);
restorecon(fd, force); restorecon(fd, force);
} else { } else {
fd = openat(dirfd, entry->d_name, O_PATH | O_NOFOLLOW | O_CLOEXEC); fd = xopenat(dirfd, entry->d_name, O_PATH | O_NOFOLLOW | O_CLOEXEC);
fgetfilecon(fd, &con); fgetfilecon(fd, &con);
if (force || strlen(con) == 0 || strcmp(con, UNLABEL_CON) == 0) if (force || strlen(con) == 0 || strcmp(con, UNLABEL_CON) == 0)
fsetfilecon(fd, SYSTEM_CON); fsetfilecon(fd, SYSTEM_CON);

View File

@ -164,7 +164,7 @@ int merge_img(const char *source, const char *target) {
if (access(source, F_OK) == -1) if (access(source, F_OK) == -1)
return 0; return 0;
if (access(target, F_OK) == -1) { if (access(target, F_OK) == -1) {
rename(source, target); xrename(source, target);
return 0; return 0;
} }
@ -188,7 +188,7 @@ int merge_img(const char *source, const char *target) {
DIR *dir; DIR *dir;
struct dirent *entry; struct dirent *entry;
if (!(dir = opendir(SOURCE_TMP))) if (!(dir = xopendir(SOURCE_TMP)))
return 1; return 1;
while ((entry = xreaddir(dir))) { while ((entry = xreaddir(dir))) {
if (entry->d_type == DT_DIR) { if (entry->d_type == DT_DIR) {

View File

@ -140,12 +140,12 @@ static void proc_name_filter(int pid) {
char buf[64]; char buf[64];
int fd; int fd;
snprintf(buf, sizeof(buf), "/proc/%d/cmdline", pid); snprintf(buf, sizeof(buf), "/proc/%d/cmdline", pid);
if ((fd = open(buf, O_RDONLY)) == -1) if (access(buf, R_OK) == -1 || (fd = xopen(buf, O_RDONLY)) == -1)
return; return;
if (fdgets(buf, sizeof(buf), fd) == 0) { if (fdgets(buf, sizeof(buf), fd) == 0) {
snprintf(buf, sizeof(buf), "/proc/%d/comm", pid); snprintf(buf, sizeof(buf), "/proc/%d/comm", pid);
close(fd); close(fd);
if ((fd = open(buf, O_RDONLY)) == -1) if (access(buf, R_OK) == -1 || (fd = xopen(buf, O_RDONLY)) == -1)
return; return;
fdgets(buf, sizeof(buf), fd); fdgets(buf, sizeof(buf), fd);
} }
@ -169,7 +169,7 @@ void unlock_blocks() {
if ((dev = xopen("/dev/block", O_RDONLY | O_CLOEXEC)) < 0) if ((dev = xopen("/dev/block", O_RDONLY | O_CLOEXEC)) < 0)
return; return;
dir = fdopendir(dev); dir = xfdopendir(dev);
while((entry = readdir(dir))) { while((entry = readdir(dir))) {
if (entry->d_type == DT_BLK) { if (entry->d_type == DT_BLK) {
@ -231,7 +231,7 @@ static int v_exec_command(int err, int *fd, void (*setupenv)(struct vector*), co
envp = environ; envp = environ;
} }
int pid = fork(); int pid = xfork();
if (pid != 0) { if (pid != 0) {
if (fd && *fd < 0) { if (fd && *fd < 0) {
// Give the read end and close write end // Give the read end and close write end
@ -308,11 +308,11 @@ int switch_mnt_ns(int pid) {
} }
int fork_dont_care() { int fork_dont_care() {
int pid = fork(); int pid = xfork();
if (pid) { if (pid) {
waitpid(pid, NULL, 0); waitpid(pid, NULL, 0);
return pid; return pid;
} else if ((pid = fork())) { } else if ((pid = xfork())) {
exit(0); exit(0);
} }
return 0; return 0;

View File

@ -1,8 +1,8 @@
/* xwrap.c - wrappers around existing library functions. /* xwrap.c - wrappers around existing library functions.
* *
* Functions with the x prefix are wrappers that either succeed or kill the * Functions with the x prefix are wrappers that either succeed or log the
* program with an error message, but never return failure. They usually have * error message. They usually have the same arguments and return value
* the same arguments and return value as the function they wrap. * as the function they wrap.
* *
*/ */
@ -57,6 +57,14 @@ int xopen3(const char *pathname, int flags, mode_t mode) {
return fd; return fd;
} }
int xopenat(int dirfd, const char *pathname, int flags) {
int fd = openat(dirfd, pathname, flags);
if (fd < 0) {
PLOGE("openat: %s", pathname);
}
return fd;
}
ssize_t xwrite(int fd, const void *buf, size_t count) { ssize_t xwrite(int fd, const void *buf, size_t count) {
int ret = write(fd, buf, count); int ret = write(fd, buf, count);
if (count != ret) { if (count != ret) {
@ -107,6 +115,14 @@ DIR *xopendir(const char *name) {
return d; return d;
} }
DIR *xfdopendir(int fd) {
DIR *d = fdopendir(fd);
if (d == NULL) {
PLOGE("fdopendir");
}
return d;
}
struct dirent *xreaddir(DIR *dirp) { struct dirent *xreaddir(DIR *dirp) {
errno = 0; errno = 0;
struct dirent *e = readdir(dirp); struct dirent *e = readdir(dirp);
@ -251,7 +267,16 @@ ssize_t xreadlink(const char *pathname, char *buf, size_t bufsiz) {
PLOGE("readlink %s", pathname); PLOGE("readlink %s", pathname);
} else { } else {
buf[ret] = '\0'; buf[ret] = '\0';
++ret; }
return ret;
}
ssize_t xreadlinkat(int dirfd, const char *pathname, char *buf, size_t bufsiz) {
ssize_t ret = readlinkat(dirfd, pathname, buf, bufsiz);
if (ret == -1) {
PLOGE("readlinkat %s", pathname);
} else {
buf[ret] = '\0';
} }
return ret; return ret;
} }
@ -290,14 +315,6 @@ int xumount2(const char *target, int flags) {
return ret; return ret;
} }
int xchmod(const char *pathname, mode_t mode) {
int ret = chmod(pathname, mode);
if (ret == -1) {
PLOGE("chmod %s %u", pathname, mode);
}
return ret;
}
int xrename(const char *oldpath, const char *newpath) { int xrename(const char *oldpath, const char *newpath) {
int ret = rename(oldpath, newpath); int ret = rename(oldpath, newpath);
if (ret == -1) { if (ret == -1) {
@ -314,6 +331,22 @@ int xmkdir(const char *pathname, mode_t mode) {
return ret; return ret;
} }
int xmkdir_p(const char *pathname, mode_t mode) {
int ret = mkdir_p(pathname, mode);
if (ret == -1) {
PLOGE("mkdir_p %s", pathname);
}
return ret;
}
int xmkdirat(int dirfd, const char *pathname, mode_t mode) {
int ret = mkdirat(dirfd, pathname, mode);
if (ret == -1 && errno != EEXIST) {
PLOGE("mkdirat %s %u", pathname, mode);
}
return ret;
}
void *xmmap(void *addr, size_t length, int prot, int flags, void *xmmap(void *addr, size_t length, int prot, int flags,
int fd, off_t offset) { int fd, off_t offset) {
void *ret = mmap(addr, length, prot, flags, fd, offset); void *ret = mmap(addr, length, prot, flags, fd, offset);
@ -331,10 +364,10 @@ ssize_t xsendfile(int out_fd, int in_fd, off_t *offset, size_t count) {
return ret; return ret;
} }
int xmkdir_p(const char *pathname, mode_t mode) { pid_t xfork() {
int ret = mkdir_p(pathname, mode); int ret = fork();
if (ret == -1) { if (ret == -1) {
PLOGE("mkdir_p %s", pathname); PLOGE("fork");
} }
return ret; return ret;
} }