Detect volume down key combo for safe mode
It is possible that a module is breaking the device so bad that zygote cannot even be started. In this case, system_server cannot start and detect the safe mode key combo, set the persist property, and reboot. Also on old Android versions, the system directly goes to safe mode after detecting a key combo without rebooting, defeating the purpose of Magisk's safe mode protection if we only check for the persist property. Directly adding key combo check natively in magiskd allows us to enter Magisk safe mode before the system is even aware of it.
This commit is contained in:
parent
3c04dab472
commit
e02e46d0fc
@ -1,11 +1,7 @@
|
|||||||
#include <sys/mount.h>
|
#include <sys/mount.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <stdlib.h>
|
#include <sys/sysmacros.h>
|
||||||
#include <stdio.h>
|
#include <linux/input.h>
|
||||||
#include <unistd.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <dirent.h>
|
|
||||||
#include <libgen.h>
|
#include <libgen.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
@ -220,6 +216,53 @@ static void collect_logs(bool reset) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define test_bit(bit, array) (array[bit / 8] & (1 << (bit % 8)))
|
||||||
|
|
||||||
|
static bool check_key_combo() {
|
||||||
|
uint8_t bitmask[(KEY_MAX + 1) / 8];
|
||||||
|
vector<int> events;
|
||||||
|
constexpr char name[] = "/dev/.ev";
|
||||||
|
|
||||||
|
// First collect candidate events that accepts volume down
|
||||||
|
for (int minor = 64; minor < 96; ++minor) {
|
||||||
|
if (xmknod(name, S_IFCHR | 0444, makedev(13, minor)))
|
||||||
|
continue;
|
||||||
|
int fd = open(name, O_RDONLY | O_CLOEXEC);
|
||||||
|
unlink(name);
|
||||||
|
if (fd < 0)
|
||||||
|
continue;
|
||||||
|
memset(bitmask, 0, sizeof(bitmask));
|
||||||
|
ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(bitmask)), bitmask);
|
||||||
|
if (test_bit(KEY_VOLUMEDOWN, bitmask))
|
||||||
|
events.push_back(fd);
|
||||||
|
else
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
|
if (events.empty())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
run_finally fin([&]{ std::for_each(events.begin(), events.end(), close); });
|
||||||
|
|
||||||
|
// Check if volume down key is held continuously for more than 3 seconds
|
||||||
|
for (int i = 0; i < 300; ++i) {
|
||||||
|
bool pressed = false;
|
||||||
|
for (const int &fd : events) {
|
||||||
|
memset(bitmask, 0, sizeof(bitmask));
|
||||||
|
ioctl(fd, EVIOCGKEY(sizeof(bitmask)), bitmask);
|
||||||
|
if (test_bit(KEY_VOLUMEDOWN, bitmask)) {
|
||||||
|
pressed = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!pressed)
|
||||||
|
return false;
|
||||||
|
// Check every 10ms
|
||||||
|
usleep(10000);
|
||||||
|
}
|
||||||
|
LOGD("KEY_VOLUMEDOWN detected: enter safe mode\n");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/****************
|
/****************
|
||||||
* Entry points *
|
* Entry points *
|
||||||
****************/
|
****************/
|
||||||
@ -260,7 +303,7 @@ void post_fs_data(int client) {
|
|||||||
goto unblock_init;
|
goto unblock_init;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getprop("persist.sys.safemode", true) == "1") {
|
if (getprop("persist.sys.safemode", true) == "1" || check_key_combo()) {
|
||||||
safe_mode = true;
|
safe_mode = true;
|
||||||
// Disable all modules and magiskhide so next boot will be clean
|
// Disable all modules and magiskhide so next boot will be clean
|
||||||
foreach_modules("disable");
|
foreach_modules("disable");
|
||||||
|
@ -48,10 +48,8 @@ static bool check_key_combo() {
|
|||||||
constexpr const char *name = "/event";
|
constexpr const char *name = "/event";
|
||||||
|
|
||||||
for (int minor = 64; minor < 96; ++minor) {
|
for (int minor = 64; minor < 96; ++minor) {
|
||||||
if (mknod(name, S_IFCHR | 0444, makedev(13, minor))) {
|
if (xmknod(name, S_IFCHR | 0444, makedev(13, minor)))
|
||||||
PLOGE("mknod");
|
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
int fd = open(name, O_RDONLY | O_CLOEXEC);
|
int fd = open(name, O_RDONLY | O_CLOEXEC);
|
||||||
unlink(name);
|
unlink(name);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
@ -60,17 +58,15 @@ static bool check_key_combo() {
|
|||||||
ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(bitmask)), bitmask);
|
ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(bitmask)), bitmask);
|
||||||
if (test_bit(KEY_VOLUMEUP, bitmask))
|
if (test_bit(KEY_VOLUMEUP, bitmask))
|
||||||
events.push_back(fd);
|
events.push_back(fd);
|
||||||
|
else
|
||||||
|
close(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (events.empty())
|
if (events.empty())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
run_finally fin([&]() -> void {
|
run_finally fin([&]{ std::for_each(events.begin(), events.end(), close); });
|
||||||
for (const int &fd : events)
|
|
||||||
close(fd);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Return true if volume key up is hold for more than 3 seconds
|
// Return true if volume up key is held for more than 3 seconds
|
||||||
int count = 0;
|
int count = 0;
|
||||||
for (int i = 0; i < 500; ++i) {
|
for (int i = 0; i < 500; ++i) {
|
||||||
for (const int &fd : events) {
|
for (const int &fd : events) {
|
||||||
|
@ -91,7 +91,7 @@ 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 ret = pipe2(pipefd, flags);
|
int ret = pipe2(pipefd, flags);
|
||||||
if (ret == -1) {
|
if (ret < 0) {
|
||||||
PLOGE("pipe2");
|
PLOGE("pipe2");
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
@ -99,7 +99,7 @@ int xpipe2(int pipefd[2], int flags) {
|
|||||||
|
|
||||||
int xsetns(int fd, int nstype) {
|
int xsetns(int fd, int nstype) {
|
||||||
int ret = setns(fd, nstype);
|
int ret = setns(fd, nstype);
|
||||||
if (ret == -1) {
|
if (ret < 0) {
|
||||||
PLOGE("setns");
|
PLOGE("setns");
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
@ -107,7 +107,7 @@ int xsetns(int fd, int nstype) {
|
|||||||
|
|
||||||
int xunshare(int flags) {
|
int xunshare(int flags) {
|
||||||
int ret = unshare(flags);
|
int ret = unshare(flags);
|
||||||
if (ret == -1) {
|
if (ret < 0) {
|
||||||
PLOGE("unshare");
|
PLOGE("unshare");
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
@ -147,7 +147,7 @@ struct dirent *xreaddir(DIR *dirp) {
|
|||||||
|
|
||||||
pid_t xsetsid() {
|
pid_t xsetsid() {
|
||||||
pid_t pid = setsid();
|
pid_t pid = setsid();
|
||||||
if (pid == -1) {
|
if (pid < 0) {
|
||||||
PLOGE("setsid");
|
PLOGE("setsid");
|
||||||
}
|
}
|
||||||
return pid;
|
return pid;
|
||||||
@ -155,7 +155,7 @@ pid_t xsetsid() {
|
|||||||
|
|
||||||
int xsocket(int domain, int type, int protocol) {
|
int xsocket(int domain, int type, int protocol) {
|
||||||
int fd = socket(domain, type, protocol);
|
int fd = socket(domain, type, protocol);
|
||||||
if (fd == -1) {
|
if (fd < 0) {
|
||||||
PLOGE("socket");
|
PLOGE("socket");
|
||||||
}
|
}
|
||||||
return fd;
|
return fd;
|
||||||
@ -163,7 +163,7 @@ int xsocket(int domain, int type, int protocol) {
|
|||||||
|
|
||||||
int xbind(int sockfd, const struct sockaddr *addr, socklen_t addrlen) {
|
int xbind(int sockfd, const struct sockaddr *addr, socklen_t addrlen) {
|
||||||
int ret = bind(sockfd, addr, addrlen);
|
int ret = bind(sockfd, addr, addrlen);
|
||||||
if (ret == -1) {
|
if (ret < 0) {
|
||||||
PLOGE("bind");
|
PLOGE("bind");
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
@ -171,7 +171,7 @@ int xbind(int sockfd, const struct sockaddr *addr, socklen_t addrlen) {
|
|||||||
|
|
||||||
int xlisten(int sockfd, int backlog) {
|
int xlisten(int sockfd, int backlog) {
|
||||||
int ret = listen(sockfd, backlog);
|
int ret = listen(sockfd, backlog);
|
||||||
if (ret == -1) {
|
if (ret < 0) {
|
||||||
PLOGE("listen");
|
PLOGE("listen");
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
@ -179,7 +179,7 @@ int xlisten(int sockfd, int backlog) {
|
|||||||
|
|
||||||
static int accept4_compat(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags) {
|
static int accept4_compat(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags) {
|
||||||
int fd = accept(sockfd, addr, addrlen);
|
int fd = accept(sockfd, addr, addrlen);
|
||||||
if (fd == -1) {
|
if (fd < 0) {
|
||||||
PLOGE("accept");
|
PLOGE("accept");
|
||||||
} else {
|
} else {
|
||||||
if (flags & SOCK_CLOEXEC)
|
if (flags & SOCK_CLOEXEC)
|
||||||
@ -194,7 +194,7 @@ static int accept4_compat(int sockfd, struct sockaddr *addr, socklen_t *addrlen,
|
|||||||
|
|
||||||
int xaccept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags) {
|
int xaccept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags) {
|
||||||
int fd = accept4(sockfd, addr, addrlen, flags);
|
int fd = accept4(sockfd, addr, addrlen, flags);
|
||||||
if (fd == -1) {
|
if (fd < 0) {
|
||||||
if (errno == ENOSYS)
|
if (errno == ENOSYS)
|
||||||
return accept4_compat(sockfd, addr, addrlen, flags);
|
return accept4_compat(sockfd, addr, addrlen, flags);
|
||||||
PLOGE("accept4");
|
PLOGE("accept4");
|
||||||
@ -228,7 +228,7 @@ void *xrealloc(void *ptr, size_t size) {
|
|||||||
|
|
||||||
ssize_t xsendmsg(int sockfd, const struct msghdr *msg, int flags) {
|
ssize_t xsendmsg(int sockfd, const struct msghdr *msg, int flags) {
|
||||||
int sent = sendmsg(sockfd, msg, flags);
|
int sent = sendmsg(sockfd, msg, flags);
|
||||||
if (sent == -1) {
|
if (sent < 0) {
|
||||||
PLOGE("sendmsg");
|
PLOGE("sendmsg");
|
||||||
}
|
}
|
||||||
return sent;
|
return sent;
|
||||||
@ -236,7 +236,7 @@ ssize_t xsendmsg(int sockfd, const struct msghdr *msg, int flags) {
|
|||||||
|
|
||||||
ssize_t xrecvmsg(int sockfd, struct msghdr *msg, int flags) {
|
ssize_t xrecvmsg(int sockfd, struct msghdr *msg, int flags) {
|
||||||
int rec = recvmsg(sockfd, msg, flags);
|
int rec = recvmsg(sockfd, msg, flags);
|
||||||
if (rec == -1) {
|
if (rec < 0) {
|
||||||
PLOGE("recvmsg");
|
PLOGE("recvmsg");
|
||||||
}
|
}
|
||||||
return rec;
|
return rec;
|
||||||
@ -253,7 +253,7 @@ int xpthread_create(pthread_t *thread, const pthread_attr_t *attr,
|
|||||||
|
|
||||||
int xstat(const char *pathname, struct stat *buf) {
|
int xstat(const char *pathname, struct stat *buf) {
|
||||||
int ret = stat(pathname, buf);
|
int ret = stat(pathname, buf);
|
||||||
if (ret == -1) {
|
if (ret < 0) {
|
||||||
PLOGE("stat %s", pathname);
|
PLOGE("stat %s", pathname);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
@ -261,7 +261,7 @@ 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 ret = lstat(pathname, buf);
|
int ret = lstat(pathname, buf);
|
||||||
if (ret == -1) {
|
if (ret < 0) {
|
||||||
PLOGE("lstat %s", pathname);
|
PLOGE("lstat %s", pathname);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
@ -269,7 +269,7 @@ int xlstat(const char *pathname, struct stat *buf) {
|
|||||||
|
|
||||||
int xfstat(int fd, struct stat *buf) {
|
int xfstat(int fd, struct stat *buf) {
|
||||||
int ret = fstat(fd, buf);
|
int ret = fstat(fd, buf);
|
||||||
if (ret == -1) {
|
if (ret < 0) {
|
||||||
PLOGE("fstat %d", fd);
|
PLOGE("fstat %d", fd);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
@ -277,7 +277,7 @@ int xfstat(int fd, struct stat *buf) {
|
|||||||
|
|
||||||
int xdup(int fd) {
|
int xdup(int fd) {
|
||||||
int ret = dup(fd);
|
int ret = dup(fd);
|
||||||
if (ret == -1) {
|
if (ret < 0) {
|
||||||
PLOGE("dup");
|
PLOGE("dup");
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
@ -285,7 +285,7 @@ int xdup(int fd) {
|
|||||||
|
|
||||||
int xdup2(int oldfd, int newfd) {
|
int xdup2(int oldfd, int newfd) {
|
||||||
int ret = dup2(oldfd, newfd);
|
int ret = dup2(oldfd, newfd);
|
||||||
if (ret == -1) {
|
if (ret < 0) {
|
||||||
PLOGE("dup2");
|
PLOGE("dup2");
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
@ -293,7 +293,7 @@ int xdup2(int oldfd, int newfd) {
|
|||||||
|
|
||||||
int xdup3(int oldfd, int newfd, int flags) {
|
int xdup3(int oldfd, int newfd, int flags) {
|
||||||
int ret = dup3(oldfd, newfd, flags);
|
int ret = dup3(oldfd, newfd, flags);
|
||||||
if (ret == -1) {
|
if (ret < 0) {
|
||||||
PLOGE("dup3");
|
PLOGE("dup3");
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
@ -301,7 +301,7 @@ int xdup3(int oldfd, int newfd, int flags) {
|
|||||||
|
|
||||||
ssize_t xreadlink(const char *pathname, char *buf, size_t bufsiz) {
|
ssize_t xreadlink(const char *pathname, char *buf, size_t bufsiz) {
|
||||||
ssize_t ret = readlink(pathname, buf, bufsiz);
|
ssize_t ret = readlink(pathname, buf, bufsiz);
|
||||||
if (ret == -1) {
|
if (ret < 0) {
|
||||||
PLOGE("readlink %s", pathname);
|
PLOGE("readlink %s", pathname);
|
||||||
} else {
|
} else {
|
||||||
buf[ret] = '\0';
|
buf[ret] = '\0';
|
||||||
@ -315,7 +315,7 @@ ssize_t xreadlinkat(int dirfd, const char *pathname, char *buf, size_t bufsiz) {
|
|||||||
#if defined(__i386__) || defined(__x86_64__)
|
#if defined(__i386__) || defined(__x86_64__)
|
||||||
memset(buf, 0, bufsiz);
|
memset(buf, 0, bufsiz);
|
||||||
ssize_t ret = readlinkat(dirfd, pathname, buf, bufsiz);
|
ssize_t ret = readlinkat(dirfd, pathname, buf, bufsiz);
|
||||||
if (ret == -1) {
|
if (ret < 0) {
|
||||||
PLOGE("readlinkat %s", pathname);
|
PLOGE("readlinkat %s", pathname);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
@ -332,7 +332,7 @@ 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 ret = symlink(target, linkpath);
|
int ret = symlink(target, linkpath);
|
||||||
if (ret == -1) {
|
if (ret < 0) {
|
||||||
PLOGE("symlink %s->%s", target, linkpath);
|
PLOGE("symlink %s->%s", target, linkpath);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
@ -340,7 +340,7 @@ int xsymlink(const char *target, const char *linkpath) {
|
|||||||
|
|
||||||
int xsymlinkat(const char *target, int newdirfd, const char *linkpath) {
|
int xsymlinkat(const char *target, int newdirfd, const char *linkpath) {
|
||||||
int ret = symlinkat(target, newdirfd, linkpath);
|
int ret = symlinkat(target, newdirfd, linkpath);
|
||||||
if (ret == -1) {
|
if (ret < 0) {
|
||||||
PLOGE("symlinkat %s->%s", target, linkpath);
|
PLOGE("symlinkat %s->%s", target, linkpath);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
@ -348,7 +348,7 @@ int xsymlinkat(const char *target, int newdirfd, const char *linkpath) {
|
|||||||
|
|
||||||
int xlinkat(int olddirfd, const char *oldpath, int newdirfd, const char *newpath, int flags) {
|
int xlinkat(int olddirfd, const char *oldpath, int newdirfd, const char *newpath, int flags) {
|
||||||
int ret = linkat(olddirfd, oldpath, newdirfd, newpath, flags);
|
int ret = linkat(olddirfd, oldpath, newdirfd, newpath, flags);
|
||||||
if (ret == -1) {
|
if (ret < 0) {
|
||||||
PLOGE("linkat %s->%s", oldpath, newpath);
|
PLOGE("linkat %s->%s", oldpath, newpath);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
@ -358,7 +358,7 @@ 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 ret = mount(source, target, filesystemtype, mountflags, data);
|
int ret = mount(source, target, filesystemtype, mountflags, data);
|
||||||
if (ret == -1) {
|
if (ret < 0) {
|
||||||
PLOGE("mount %s->%s", source, target);
|
PLOGE("mount %s->%s", source, target);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
@ -366,7 +366,7 @@ int xmount(const char *source, const char *target,
|
|||||||
|
|
||||||
int xumount(const char *target) {
|
int xumount(const char *target) {
|
||||||
int ret = umount(target);
|
int ret = umount(target);
|
||||||
if (ret == -1) {
|
if (ret < 0) {
|
||||||
PLOGE("umount %s", target);
|
PLOGE("umount %s", target);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
@ -374,7 +374,7 @@ int xumount(const char *target) {
|
|||||||
|
|
||||||
int xumount2(const char *target, int flags) {
|
int xumount2(const char *target, int flags) {
|
||||||
int ret = umount2(target, flags);
|
int ret = umount2(target, flags);
|
||||||
if (ret == -1) {
|
if (ret < 0) {
|
||||||
PLOGE("umount2 %s", target);
|
PLOGE("umount2 %s", target);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
@ -382,7 +382,7 @@ int xumount2(const char *target, int flags) {
|
|||||||
|
|
||||||
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 < 0) {
|
||||||
PLOGE("rename %s->%s", oldpath, newpath);
|
PLOGE("rename %s->%s", oldpath, newpath);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
@ -390,7 +390,7 @@ 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 ret = mkdir(pathname, mode);
|
int ret = mkdir(pathname, mode);
|
||||||
if (ret == -1 && errno != EEXIST) {
|
if (ret < 0 && errno != EEXIST) {
|
||||||
PLOGE("mkdir %s %u", pathname, mode);
|
PLOGE("mkdir %s %u", pathname, mode);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
@ -398,7 +398,7 @@ int xmkdir(const char *pathname, mode_t mode) {
|
|||||||
|
|
||||||
int xmkdirs(const char *pathname, mode_t mode) {
|
int xmkdirs(const char *pathname, mode_t mode) {
|
||||||
int ret = mkdirs(pathname, mode);
|
int ret = mkdirs(pathname, mode);
|
||||||
if (ret == -1) {
|
if (ret < 0) {
|
||||||
PLOGE("mkdirs %s", pathname);
|
PLOGE("mkdirs %s", pathname);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
@ -406,7 +406,7 @@ int xmkdirs(const char *pathname, mode_t mode) {
|
|||||||
|
|
||||||
int xmkdirat(int dirfd, const char *pathname, mode_t mode) {
|
int xmkdirat(int dirfd, const char *pathname, mode_t mode) {
|
||||||
int ret = mkdirat(dirfd, pathname, mode);
|
int ret = mkdirat(dirfd, pathname, mode);
|
||||||
if (ret == -1 && errno != EEXIST) {
|
if (ret < 0 && errno != EEXIST) {
|
||||||
PLOGE("mkdirat %s %u", pathname, mode);
|
PLOGE("mkdirat %s %u", pathname, mode);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
@ -431,7 +431,7 @@ ssize_t xsendfile(int out_fd, int in_fd, off_t *offset, size_t count) {
|
|||||||
|
|
||||||
pid_t xfork() {
|
pid_t xfork() {
|
||||||
int ret = fork();
|
int ret = fork();
|
||||||
if (ret == -1) {
|
if (ret < 0) {
|
||||||
PLOGE("fork");
|
PLOGE("fork");
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
@ -439,7 +439,7 @@ pid_t xfork() {
|
|||||||
|
|
||||||
int xpoll(struct pollfd *fds, nfds_t nfds, int timeout) {
|
int xpoll(struct pollfd *fds, nfds_t nfds, int timeout) {
|
||||||
int ret = poll(fds, nfds, timeout);
|
int ret = poll(fds, nfds, timeout);
|
||||||
if (ret == -1) {
|
if (ret < 0) {
|
||||||
PLOGE("poll");
|
PLOGE("poll");
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
@ -447,7 +447,7 @@ int xpoll(struct pollfd *fds, nfds_t nfds, int timeout) {
|
|||||||
|
|
||||||
int xinotify_init1(int flags) {
|
int xinotify_init1(int flags) {
|
||||||
int ret = inotify_init1(flags);
|
int ret = inotify_init1(flags);
|
||||||
if (ret == -1) {
|
if (ret < 0) {
|
||||||
PLOGE("inotify_init1");
|
PLOGE("inotify_init1");
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
@ -463,3 +463,11 @@ char *xrealpath(const char *path, char *resolved_path) {
|
|||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int xmknod(const char *pathname, mode_t mode, dev_t dev) {
|
||||||
|
int ret = mknod(pathname, mode, dev);
|
||||||
|
if (ret < 0) {
|
||||||
|
PLOGE("mknod");
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
@ -59,4 +59,5 @@ pid_t xfork();
|
|||||||
int xpoll(struct pollfd *fds, nfds_t nfds, int timeout);
|
int xpoll(struct pollfd *fds, nfds_t nfds, int timeout);
|
||||||
int xinotify_init1(int flags);
|
int xinotify_init1(int flags);
|
||||||
char *xrealpath(const char *path, char *resolved_path);
|
char *xrealpath(const char *path, char *resolved_path);
|
||||||
|
int xmknod(const char *pathname, mode_t mode, dev_t dev);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user