minecraft-pi-reborn/media-layer/proxy/src/client/client.cpp

91 lines
2.5 KiB
C++

#include <vector>
#include <cerrno>
#include <unistd.h>
#include <cstring>
#include <sys/prctl.h>
#include <csignal>
#include "../common/common.h"
// Store Handlers
__attribute__((const)) static std::vector<proxy_handler_t> &get_handlers() {
static std::vector<proxy_handler_t> handlers;
return handlers;
}
void _add_handler(unsigned char unique_id, proxy_handler_t handler) {
if (get_handlers().size() > unique_id && get_handlers()[unique_id] != NULL) {
PROXY_ERR("Duplicate ID: %i", (int) unique_id);
}
if (get_handlers().size() <= unique_id) {
get_handlers().resize(unique_id + 1);
}
get_handlers()[unique_id] = handler;
}
// Store Parent PID
static int parent_is_alive = 1;
static void sigusr1_handler(__attribute__((unused)) int sig) {
// Mark Parent As Dead
parent_is_alive = 0;
}
// Check State Of Proxy And Exit If Invalid
void _check_proxy_state() {
// Check Server State
if (!parent_is_alive) {
PROXY_ERR("%s", "Server Terminated");
}
}
// Main
int main(int argc, char *argv[]) {
// Ignore SIGINT, Send Signal To Parent
signal(SIGINT, SIG_IGN);
// Send Signal On Parent Death To Interrupt Connection Read/Write And Exit
prctl(PR_SET_PDEATHSIG, SIGUSR1);
struct sigaction sa;
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_NOCLDSTOP;
sa.sa_handler = &sigusr1_handler;
if (sigaction(SIGUSR1, &sa, NULL) == -1) {
PROXY_ERR("Unable To Install Signal Handler: %s", strerror(errno));
}
// Get Connection
if (argc != 3) {
PROXY_ERR("%s", "Invalid Arguments");
}
char *read_str = argv[1];
char *write_str = argv[2];
set_connection(atoi(read_str), atoi(write_str));
PROXY_INFO("%s", "Connected");
// Send Connection Message
write_string((char *) CONNECTED_MSG);
flush_write_cache();
// Loop
int running = is_connection_open();
while (running) {
unsigned char unique_id = read_byte();
if (get_handlers().size() > unique_id && get_handlers()[unique_id] != NULL) {
// Run Method
get_handlers()[unique_id]();
// Check If Connection Is Still Open
if (!is_connection_open()) {
// Exit
running = 0;
} else {
// Flush Write Cache
flush_write_cache();
}
} else {
PROXY_ERR("Invalid Method ID: %i", (int) unique_id);
}
}
// Exit
PROXY_INFO("%s", "Stopped");
return 0;
}