diff --git a/client/src/sock.c b/client/src/sock.c index 40b8517..a726a82 100644 --- a/client/src/sock.c +++ b/client/src/sock.c @@ -1,5 +1,6 @@ // sock.c +#include #include #include #include @@ -7,6 +8,8 @@ #include "sock.h" enum error_t sock_init(int *sockptr) { + assert(sockptr != NULL); + int const sock = socket(AF_UNIX, SOCK_STREAM, 0); if (sock < 0) goto sock_init_error; diff --git a/server/src/data.h b/server/src/data.h new file mode 100644 index 0000000..642700b --- /dev/null +++ b/server/src/data.h @@ -0,0 +1,9 @@ +#ifndef DAEMON_DATA_H +#define DAEMON_DATA_H + +struct data_t { + int socket; + int socket_accept; +}; + +#endif diff --git a/server/src/main.c b/server/src/main.c index 6916522..a26d167 100644 --- a/server/src/main.c +++ b/server/src/main.c @@ -11,15 +11,27 @@ #include "opts.h" #include "sock.h" +#include "data.h" static void handle_signal(int _) { - remove("/tmp/swd.sock"); + remove(SOCK_PATH); exit(0); } +enum error_t game_loop(struct data_t *data) { + char buffer[1024] = { 0 }; + + read(data->socket_accept, buffer, 1024); + write(data->socket_accept, buffer, 1024); + + return ERR_OK; +} + + int main(int argc, char **argv) { enum error_t err = ERR_OK; + struct data_t daemon_data = { 0 }; signal(SIGINT, handle_signal); signal(SIGTERM, handle_signal); @@ -33,35 +45,16 @@ int main(int argc, char **argv) { err = opts_init(&options); if (err) goto handle_error; - int sock; - err = sock_init(&sock); + err = sock_loop(&daemon_data, game_loop); if (err) goto handle_error; - // Can I move this into its own function that takes a function pointer? - for (int sock_accept; ;) { - sock_accept = accept(sock, NULL, NULL); - if (sock_accept < 0) { err = ERR_SOCKET; goto handle_error_socket; } - - char ibuf[1028] = { 0 }; - - // Just echoing everything back for now - read(sock_accept, ibuf, 1028); - write(sock_accept, ibuf, 1028); - - close(sock_accept); - } - - close(sock); - remove("/tmp/swd.sock"); opts_free(&options); return ERR_OK; -handle_error_socket: - close(sock); - remove("/tmp/swd.sock"); handle_error: if (options.daemonise) syslog(LOG_ERR, "%s", ERROR_STRS[err]); opts_free(&options); + handle_error_pre_opts: printf("ERROR: %s\n", ERROR_STRS[err]); return err; diff --git a/server/src/sock.c b/server/src/sock.c index 989e339..30f3cc7 100644 --- a/server/src/sock.c +++ b/server/src/sock.c @@ -1,5 +1,6 @@ // sock.c +#include #include #include #include @@ -8,26 +9,65 @@ #include "sock.h" enum error_t sock_init(int *sockptr) { + assert(sockptr != NULL); + int const sock = socket(AF_UNIX, SOCK_STREAM, 0); if (sock < 0) goto sock_init_error; struct sockaddr_un sa = { 0 }; sa.sun_family = AF_UNIX; - strcpy(sa.sun_path, "/tmp/swd.sock"); - // Socket path should be a shared setting between server and client - remove("/tmp/swd.sock"); + strcpy(sa.sun_path, SOCK_PATH); + remove(SOCK_PATH); + // Should be redundant but it doesn't hurt to be sure if (bind(sock, (struct sockaddr *)&sa, sizeof(sa))) goto sock_error; - if (listen(sock, 4096) < 0) goto sock_error; *sockptr = sock; return ERR_OK; sock_error: - close(sock); - remove("/tmp/swd.sock"); + sock_free(&sock); + sock_init_error: return ERR_SOCKET; } + + +void sock_free(int const *sockptr) { + assert(sockptr != NULL); + + close(*sockptr); + remove(SOCK_PATH); +} + + +enum error_t sock_loop(struct data_t *data, gameloop_fn fn) { + assert(data != NULL); + + enum error_t err = ERR_OK; + + if ((err = sock_init(&data->socket))) return err; + + for (int sock_accept;;) { + if ((sock_accept = accept(data->socket, NULL, NULL)) < 0) { + err = ERR_SOCKET; + goto sock_loop_end_pre; + }; + + data->socket_accept = sock_accept; + if ((err = fn(data))) goto sock_loop_end_pre; + + close(data->socket_accept); + continue; + +sock_loop_end_pre: + close(data->socket_accept); + goto sock_loop_end; + } + +sock_loop_end: + sock_free(&data->socket); + return err; +} diff --git a/server/src/sock.h b/server/src/sock.h index fa54a69..b5b4a46 100644 --- a/server/src/sock.h +++ b/server/src/sock.h @@ -3,6 +3,15 @@ #include "error.h" +#include "data.h" + +#define SOCK_PATH "/tmp/swd.sock" + // Socket path should be a shared setting between server and client + enum error_t sock_init(int *); +void sock_free(int const *); + +typedef enum error_t (* gameloop_fn)(struct data_t *);; +enum error_t sock_loop(struct data_t *, gameloop_fn); #endif