From 666eedb9e858b6eb507a283012fc3bb215953f0e Mon Sep 17 00:00:00 2001 From: "Jay Freeman (saurik)" <saurik@saurik.com> Date: Tue, 10 Sep 2013 12:28:55 -0700 Subject: [PATCH] Allow for connections from the client to the server. --- Console.cpp | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++++ Handler.mm | 52 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 108 insertions(+) diff --git a/Console.cpp b/Console.cpp index 3dede2f..fe03c31 100644 --- a/Console.cpp +++ b/Console.cpp @@ -47,9 +47,11 @@ #include <errno.h> #include <unistd.h> +#include <sys/socket.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> +#include <netdb.h> #include <sys/types.h> #include <sys/socket.h> @@ -616,6 +618,9 @@ int Main(int argc, char const * const argv[], char const * const envp[]) { pid_t pid(_not(pid_t)); #endif + const char *host(NULL); + const char *port(NULL); + apr_getopt_t *state; _aprcall(apr_getopt_init(&state, pool, argc, argv)); @@ -628,6 +633,7 @@ int Main(int argc, char const * const argv[], char const * const envp[]) { #ifdef CY_ATTACH "p:" #endif + "r:" "s" , &opt, &arg)); @@ -641,6 +647,7 @@ int Main(int argc, char const * const argv[], char const * const envp[]) { #ifdef CY_ATTACH " [-p <pid|name>]" #endif + " [-r <host:port>]" " [<script> [<arg>...]]\n" ); return 1; @@ -728,6 +735,27 @@ int Main(int argc, char const * const argv[], char const * const envp[]) { } break; #endif + case 'r': { + //size_t size(strlen(arg)); + + char *colon(strrchr(arg, ':')); + if (colon == NULL) { + fprintf(stderr, "missing colon in hostspec\n"); + return 1; + } + + /*char *end; + port = strtoul(colon + 1, &end, 10); + if (end != arg + size) { + fprintf(stderr, "invalid port in hostspec\n"); + return 1; + }*/ + + host = arg; + *colon = '\0'; + port = colon + 1; + } break; + case 's': strict_ = true; break; @@ -800,6 +828,34 @@ int Main(int argc, char const * const argv[], char const * const envp[]) { client_ = -1; #endif + if (client_ == -1 && host != NULL && port != NULL) { + struct addrinfo hints; + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = 0; + hints.ai_flags = 0; + + struct addrinfo *infos; + _syscall(getaddrinfo(host, port, &hints, &infos)); + + _assert(infos != NULL); try { + for (struct addrinfo *info(infos); info != NULL; info = info->ai_next) { + int client(_syscall(socket(info->ai_family, info->ai_socktype, info->ai_protocol))); try { + _syscall(connect(client, info->ai_addr, info->ai_addrlen)); + client_ = client; + break; + } catch (...) { + _syscall(close(client)); + throw; + } + } + } catch (...) { + freeaddrinfo(infos); + throw; + } + } + if (script == NULL && tty) Console(options); else { diff --git a/Handler.mm b/Handler.mm index d15eb6a..e7b2c3b 100644 --- a/Handler.mm +++ b/Handler.mm @@ -172,3 +172,55 @@ extern "C" void CYHandleServer(pid_t pid) { fprintf(stderr, "%s\n", error.PoolCString(pool)); } } + +struct CYServer { + pthread_t thread_; + uint16_t port_; + int socket_; + + CYServer(uint16_t port) : + port_(port), + socket_(-1) + { + } + + ~CYServer() { + if (socket_ != -1) + _syscall(close(socket_)); + } + + void Listen() { + socket_ = _syscall(::socket(PF_INET, SOCK_STREAM, 0)); try { + sockaddr_in address; + address.sin_family = AF_INET; + address.sin_addr.s_addr = INADDR_ANY; + address.sin_port = htons(port_); + _syscall(::bind(socket_, reinterpret_cast<sockaddr *>(&address), sizeof(address))); + + _syscall(::listen(socket_, -1)); + + for (;;) { + socklen_t length(sizeof(address)); + int socket(_syscall(::accept(socket_, reinterpret_cast<sockaddr *>(&address), &length))); + CYHandleClient(socket); + } + } catch (const CYException &error) { + CYPool pool; + fprintf(stderr, "%s\n", error.PoolCString(pool)); + } + } +}; + +static void *OnServer(void *data) { + CYServer *server(reinterpret_cast<CYServer *>(data)); + server->Listen(); + delete server; + return NULL; +} + +extern "C" void CYListenServer(short port) { + CYInitializeDynamic(); + + CYServer *server(new CYServer(port)); + _assert(pthread_create(&server->thread_, NULL, &OnServer, server) == 0); +} -- 2.47.2