mirror of
https://github.com/topjohnwu/Magisk.git
synced 2025-12-22 23:26:42 -08:00
Migrate exec function to C++ arrays
This commit is contained in:
@@ -193,3 +193,78 @@ ssize_t __getline(char **lineptr, size_t *n, FILE *stream) {
|
||||
int __fsetxattr(int fd, const char *name, const void *value, size_t size, int flags) {
|
||||
return (int) syscall(__NR_fsetxattr, fd, name, value, size, flags);
|
||||
}
|
||||
|
||||
/*
|
||||
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
|
||||
*cb -> A callback function which calls after forking
|
||||
*/
|
||||
int exec_array(int err, int *fd, void (*cb)(void), const char *argv[]) {
|
||||
int pipefd[2], write_end = -1;
|
||||
|
||||
if (fd) {
|
||||
if (*fd < 0) {
|
||||
if (xpipe2(pipefd, O_CLOEXEC) == -1)
|
||||
return -1;
|
||||
write_end = pipefd[1];
|
||||
} else {
|
||||
write_end = *fd;
|
||||
}
|
||||
}
|
||||
|
||||
int pid = xfork();
|
||||
if (pid != 0) {
|
||||
if (fd && *fd < 0) {
|
||||
// Give the read end and close write end
|
||||
*fd = pipefd[0];
|
||||
close(pipefd[1]);
|
||||
}
|
||||
return pid;
|
||||
}
|
||||
|
||||
if (fd) {
|
||||
xdup2(write_end, STDOUT_FILENO);
|
||||
if (err)
|
||||
xdup2(write_end, STDERR_FILENO);
|
||||
}
|
||||
|
||||
// Setup environment
|
||||
if (cb)
|
||||
cb();
|
||||
|
||||
execvp(argv[0], (char **) argv);
|
||||
PLOGE("execvp %s", argv[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int v_exec_command(int err, int *fd, void (*cb)(void), const char *argv0, va_list argv) {
|
||||
// Collect va_list into vector
|
||||
Array<const char *> args;
|
||||
args.push_back(argv0);
|
||||
for (const char *arg = va_arg(argv, char*); arg; arg = va_arg(argv, char*))
|
||||
args.push_back(arg);
|
||||
args.push_back(nullptr);
|
||||
int pid = exec_array(err, fd, cb, args.data());
|
||||
return pid;
|
||||
}
|
||||
|
||||
int exec_command_sync(const char *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 (*cb)(void), const char *argv0, ...) {
|
||||
va_list argv;
|
||||
va_start(argv, argv0);
|
||||
int pid = v_exec_command(err, fd, cb, argv0, argv);
|
||||
va_end(argv);
|
||||
return pid;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user