summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMikhail Burakov <mburakov@mailbox.org>2023-04-02 20:44:29 +0200
committerMikhail Burakov <mburakov@mailbox.org>2023-04-07 13:48:05 +0200
commit0107291f780228edd3bae34cca59974a5734feda (patch)
tree01ae90199beec40c783dd9a70b9522b785e76200
parent20ed57016563c10157093ed3785f17b5ce27fdca (diff)
Connect to socket instead of reading stdin
-rw-r--r--main.c58
1 files changed, 54 insertions, 4 deletions
diff --git a/main.c b/main.c
index bc8c736..ec05612 100644
--- a/main.c
+++ b/main.c
@@ -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;
}