71 lines
2.0 KiB
C++
71 lines
2.0 KiB
C++
#include <unistd.h>
|
|
#include <cerrno>
|
|
#include <cstring>
|
|
#include <string>
|
|
#include <sys/wait.h>
|
|
|
|
#include <trampoline/types.h>
|
|
|
|
#include "pipe.h"
|
|
|
|
#include "../log.h"
|
|
#include "../trampoline.h"
|
|
#include "../memory.h"
|
|
|
|
// Setup Pipes
|
|
#define PIPE_READ 0
|
|
#define PIPE_WRITE 1
|
|
static int arguments_pipe[2];
|
|
static int return_value_pipe[2];
|
|
static void safe_pipe(int *out) {
|
|
int ret = pipe(out);
|
|
if (ret != 0) {
|
|
ERR("Unable To Create Pipe: %s", strerror(errno));
|
|
}
|
|
}
|
|
void init_pipe_common() {
|
|
safe_pipe(arguments_pipe);
|
|
safe_pipe(return_value_pipe);
|
|
}
|
|
|
|
// Guest
|
|
void init_pipe_guest() {
|
|
// Close Unneeded Pipes
|
|
close(arguments_pipe[PIPE_READ]);
|
|
close(return_value_pipe[PIPE_WRITE]);
|
|
// Setup Environment
|
|
setenv(TRAMPOLINE_ARGUMENTS_PIPE_ENV, std::to_string(arguments_pipe[PIPE_WRITE]).c_str(), true);
|
|
setenv(TRAMPOLINE_RETURN_VALUE_PIPE_ENV, std::to_string(return_value_pipe[PIPE_READ]).c_str(), true);
|
|
}
|
|
|
|
// Host
|
|
void init_pipe_host(pid_t guest_pid) {
|
|
// Close Unneeded Pipes
|
|
close(arguments_pipe[PIPE_WRITE]);
|
|
close(return_value_pipe[PIPE_READ]);
|
|
// Wait For Commands
|
|
trampoline_pipe_arguments cmd = {};
|
|
while (read(arguments_pipe[PIPE_READ], &cmd, sizeof(trampoline_pipe_arguments)) > 0) {
|
|
static unsigned char args[MAX_TRAMPOLINE_ARGS_SIZE];
|
|
memory_reader(cmd.args_addr, args, cmd.length);
|
|
uint32_t ret = 0;
|
|
if (cmd.allow_early_return && cmd.length > 0) {
|
|
write(return_value_pipe[PIPE_WRITE], &ret, sizeof(uint32_t));
|
|
}
|
|
ret = trampoline(cmd.id, args);
|
|
if (!cmd.allow_early_return) {
|
|
write(return_value_pipe[PIPE_WRITE], &ret, sizeof(uint32_t));
|
|
}
|
|
}
|
|
// Reap Child
|
|
int status;
|
|
if (waitpid(guest_pid, &status, 0) == -1) {
|
|
ERR("Unable To Reap Child: %s", strerror(errno));
|
|
}
|
|
// Exit
|
|
if (WIFEXITED(status)) {
|
|
exit(WEXITSTATUS(status));
|
|
} else {
|
|
ERR("Unable To Determine Exit Code");
|
|
}
|
|
} |