diff --git a/server/socket_server.c b/server/socket_server.c new file mode 100644 index 0000000..8757ca6 --- /dev/null +++ b/server/socket_server.c @@ -0,0 +1,70 @@ +#include "socket_server.h" +#include +#include +#include +#include +#include +#include + +/** + * Gets the address info for the given port, such that the server will listen on 0.0.0. + * + * @param port The port to listen on. + * @param info A pointer to a location where getaddrinfo can store data. + * + * @return The result of getaddrinfo. See `man getaddrinfo` for details. + */ +static int build_addr_info(int port, struct addrinfo **info) { + struct addrinfo hints = {.ai_family = AF_UNSPEC, .ai_socktype = SOCK_STREAM}; + // Get the number of chars in the port + int port_length = floor(log10(port)) + 1; + char *port_string = malloc((port_length + 1) * sizeof(char)); + sprintf(port_string, "%d", port); + + int addr_status = getaddrinfo(NULL, port_string, &hints, info); + free(port_string); + + return addr_status; +} + +/** + * Setup the server's socket for listening. + * + * @param port The port to listen on. + * + * @return A server_info representing the result of setting up the socket. + */ +struct server_info setup(int port) { + struct server_info info = {.sock_fd = -1}; + struct addrinfo *addr_info; + int addr_status = build_addr_info(port, &addr_info); + if (addr_status != 0) { + info.status = STATUS_ERROR; + return info; + } + + info.sock_fd = socket(addr_info->ai_family, addr_info->ai_socktype, addr_info->ai_protocol); + if (info.sock_fd == -1) { + info.status = STATUS_ERROR; + return info; + } + + int bind_result = bind(info.sock_fd, addr_info->ai_addr, addr_info->ai_addrlen); + if (bind_result == -1) { + close(info.sock_fd); + info.sock_fd = -1; + info.status = STATUS_ERROR; + return info; + } + + int listen_result = listen(info.sock_fd, 8); + if (listen_result == -1) { + close(info.sock_fd); + info.sock_fd = -1; + info.status = STATUS_ERROR; + return info; + } + info.status = STATUS_LISTENING; + + return info; +} diff --git a/server/socket_server.h b/server/socket_server.h new file mode 100644 index 0000000..adbcbf9 --- /dev/null +++ b/server/socket_server.h @@ -0,0 +1,15 @@ +#ifndef SOCKET_SERVER +#define SOCKET_SERVER + +#define BACKLOG_SIZE 8; + +enum server_status {STATUS_LISTENING, STATUS_CLOSED, STATUS_ERROR}; +struct server_info { + int sock_fd; + enum server_status status; +}; + +struct server_info setup(int port); +char *serve(struct server_info *info); + +#endif