From 906923ad3f2ecb2c73d286924e2ac05f8f3ae502 Mon Sep 17 00:00:00 2001 From: Anton Kling Date: Mon, 9 Dec 2024 17:29:07 +0100 Subject: tcpserver: Add the basics of tcpserver --- userland/tcpserver/tcpserver.c | 78 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 userland/tcpserver/tcpserver.c (limited to 'userland/tcpserver/tcpserver.c') diff --git a/userland/tcpserver/tcpserver.c b/userland/tcpserver/tcpserver.c new file mode 100644 index 0000000..90660df --- /dev/null +++ b/userland/tcpserver/tcpserver.c @@ -0,0 +1,78 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void usage(char *program_name) { + fprintf(stderr, "Usage: %s host port program [arg...]\n", program_name); +} + +int main(int argc, char **argv) { + if (argc < 4) { + usage(*argv); + return 1; + } + char *host = *(argv + 1); + if ('-' == *host) { + fprintf(stderr, "Sorry, command line arguments are not supported\n"); + return 1; + } + char *port = *(argv + 2); + char *program = *(argv + 3); + // The arguments beign at argv + 4 but + // argv[0] should be "program" anyways. + char **program_arguments = argv + 3; + + int port_number = atoi(port); + if (0 == port_number) { + fprintf(stderr, "Invalid port: %s\n", port); + return 1; + } + + int sockfd = socket(AF_INET, SOCK_STREAM, 0); + if (-1 == sockfd) { + perror("socket"); + return 1; + } + + struct sockaddr_in servaddr; + memset(&servaddr, 0, sizeof(servaddr)); + + servaddr.sin_family = AF_INET; + servaddr.sin_addr.s_addr = htonl(INADDR_ANY); + servaddr.sin_port = htons(port_number); + + if (-1 == bind(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr))) { + perror("bind"); + return 1; + } + + for (;;) { + struct sockaddr_in cli; + socklen_t len = sizeof(cli); + int connfd = accept(sockfd, (struct sockaddr *)&cli, &len); + if (-1 == connfd) { + perror("accept"); + continue; + } + + if (0 == fork()) { + dup2(connfd, 0); + dup2(connfd, 1); + assert(-1 == execv(program, program_arguments)); + perror("execv"); + return 1; + } + close(connfd); + } + + close(sockfd); + return 0; +} -- cgit v1.2.3