diff options
author | Anton Kling <anton@kling.gg> | 2024-12-09 17:29:07 +0100 |
---|---|---|
committer | Anton Kling <anton@kling.gg> | 2024-12-09 17:29:07 +0100 |
commit | 906923ad3f2ecb2c73d286924e2ac05f8f3ae502 (patch) | |
tree | 73a94e1b30ccce6993726c31dfabaa4343d3a1a2 | |
parent | 1d2c7ff3548c39c47b0d92a2928d8595f17a66c3 (diff) |
tcpserver: Add the basics of tcpserver
-rwxr-xr-x | meta/userland.sh | 2 | ||||
-rw-r--r-- | userland/tcpserver/Makefile | 16 | ||||
-rw-r--r-- | userland/tcpserver/tcpserver.c | 78 |
3 files changed, 96 insertions, 0 deletions
diff --git a/meta/userland.sh b/meta/userland.sh index b403215..2307f02 100755 --- a/meta/userland.sh +++ b/meta/userland.sh @@ -21,6 +21,7 @@ make -j`nproc` -C ./userland/nasm-2.16.01 make -j`nproc` -C ./userland/dns make -j`nproc` -C ./userland/to make -j`nproc` -C ./userland/httpd +make -j`nproc` -C ./userland/tcpserver mkdir sysroot sudo cp ./userland/rtl8139/rtl8139 ./sysroot/rtl8139 @@ -37,6 +38,7 @@ sudo cp ./userland/nasm-2.16.01/nasm ./sysroot/nasm sudo cp ./userland/dns/dns ./sysroot/dns sudo cp ./userland/to/to ./sysroot/to sudo cp ./userland/httpd/httpd ./sysroot/httpd +sudo cp ./userland/tcpserver/tcpserver ./sysroot/tcpserver cd ./sysroot rm ./init diff --git a/userland/tcpserver/Makefile b/userland/tcpserver/Makefile new file mode 100644 index 0000000..c91e351 --- /dev/null +++ b/userland/tcpserver/Makefile @@ -0,0 +1,16 @@ +CC="i686-sb-gcc" +CFLAGS=-Wall -Wextra -pedantic -Werror -g +LDFLAGS= +OBJS=tcpserver.o +BIN=tcpserver +all: $(BIN) + +%.o: %.c + clang-format -i $< + $(CC) -c -o $@ $< $(CFLAGS) + +$(BIN): $(OBJS) + $(CC) $(LDFLAGS) -o $@ $^ + +clean: + rm $(BIN) $(OBJS) 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 <arpa/inet.h> +#include <assert.h> +#include <dirent.h> +#include <errno.h> +#include <fcntl.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/socket.h> +#include <unistd.h> + +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; +} |