diff options
author | Mikhail Burakov <mburakov@mailbox.org> | 2023-04-02 20:44:29 +0200 |
---|---|---|
committer | Mikhail Burakov <mburakov@mailbox.org> | 2023-04-07 13:48:05 +0200 |
commit | 0107291f780228edd3bae34cca59974a5734feda (patch) | |
tree | 01ae90199beec40c783dd9a70b9522b785e76200 | |
parent | 20ed57016563c10157093ed3785f17b5ce27fdca (diff) |
Connect to socket instead of reading stdin
-rw-r--r-- | main.c | 58 |
1 files changed, 54 insertions, 4 deletions
@@ -15,10 +15,14 @@ * along with receiver. If not, see <https://www.gnu.org/licenses/>. */ +#include <arpa/inet.h> #include <errno.h> +#include <netinet/in.h> +#include <netinet/tcp.h> #include <poll.h> #include <signal.h> #include <stddef.h> +#include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -31,6 +35,48 @@ static volatile sig_atomic_t g_signal; static void OnSignal(int status) { g_signal = status; } +static void SocketDtor(int* sock) { + if (*sock == -1) return; + close(*sock); + *sock = -1; +} + +static int ConnectSocket(const char* arg) { + uint16_t port; + char ip[sizeof("xxx.xxx.xxx.xxx")]; + if (sscanf(arg, "%[0-9.]:%hu", ip, &port) != 2) { + LOG("Failed to parse address"); + return -1; + } + + int sock = socket(AF_INET, SOCK_STREAM, 0); + if (sock == -1) { + LOG("Failed to create socket (%s)", strerror(errno)); + return -1; + } + static const int one = 1; + if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &one, sizeof(one))) { + LOG("Failed to set TCP_NODELAY (%s)", strerror(errno)); + goto rollback_sock; + } + + // TODO(mburakov): Set and maintain TCP_QUICKACK. + const struct sockaddr_in addr = { + .sin_family = AF_INET, + .sin_port = htons(port), + .sin_addr.s_addr = inet_addr(ip), + }; + if (connect(sock, (const struct sockaddr*)&addr, sizeof(addr))) { + LOG("Failed to connect socket (%s)", strerror(errno)); + goto rollback_sock; + } + return sock; + +rollback_sock: + close(sock); + return -1; +} + static void OnWindowClose(void* user) { (void)user; g_signal = SIGINT; @@ -53,8 +99,12 @@ static void DecodeContextDtor(struct DecodeContext** decode_context) { } int main(int argc, char* argv[]) { - (void)argc; - (void)argv; + if (argc < 2) { + LOG("Usage: %s <ip>:<port>", argv[0]); + return EXIT_FAILURE; + } + int __attribute__((cleanup(SocketDtor))) sock = ConnectSocket(argv[1]); + if (sock == -1) return EXIT_FAILURE; static const struct WindowEventHandlers window_event_handlers = { .OnClose = OnWindowClose, @@ -89,7 +139,7 @@ int main(int argc, char* argv[]) { while (!g_signal) { struct pollfd pfds[] = { - {.fd = STDIN_FILENO, .events = POLLIN}, + {.fd = sock, .events = POLLIN}, {.fd = events_fd, .events = POLLIN}, }; switch (poll(pfds, LENGTH(pfds), -1)) { @@ -104,7 +154,7 @@ int main(int argc, char* argv[]) { default: break; } - if (pfds[0].revents && !DecodeContextDecode(decode_context, STDIN_FILENO)) { + if (pfds[0].revents && !DecodeContextDecode(decode_context, sock)) { LOG("Failed to decode incoming data"); return EXIT_FAILURE; } |