diff options
author | Ivan Davydov <lotigara@lotigara.ru> | 2025-06-17 14:32:27 +0300 |
---|---|---|
committer | Ivan Davydov <lotigara@lotigara.ru> | 2025-06-17 14:32:27 +0300 |
commit | 9d945cd7e55c7d4f432dbe8ea758178fadd44b04 (patch) | |
tree | 1a793e9fe1c2defe25ab5d687f20798ecbf34bb0 |
Initial commit
-rw-r--r-- | CREDITS | 4 | ||||
-rw-r--r-- | Makefile | 10 | ||||
-rw-r--r-- | acccre-server.c | 132 | ||||
-rw-r--r-- | acccre-server.h | 25 | ||||
-rwxr-xr-x | client.py | 27 |
5 files changed, 198 insertions, 0 deletions
@@ -0,0 +1,4 @@ +Server +====== +* https://github.com/JeffreytheCoder/Simple-HTTP-Server/blob/master/server.c +* https://codereview.stackexchange.com/questions/284179/proper-implementation-of-signal-handler-and-multithreading-pthread diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..796bed8 --- /dev/null +++ b/Makefile @@ -0,0 +1,10 @@ +.POSIX: +CC = tcc +CFLAGS = -Wall +#CPPFLAGS = -D UNIX +LDLIBS = -lpthread -lrt + +all: acccre-server +acccre-server: acccre-server.o +clean: + rm -f *.o acccre-server diff --git a/acccre-server.c b/acccre-server.c new file mode 100644 index 0000000..310317a --- /dev/null +++ b/acccre-server.c @@ -0,0 +1,132 @@ +#ifdef __unix__ +#include "acccre-server.h" + +#include <memory.h> +#include <netdb.h> +/*#ifdef INET*/ + #include <netinet/in.h> +/*#endif*/ +#include <pthread.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <strings.h> +#include <sys/socket.h> +#include <sys/types.h> +/*#ifdef UNIX*/ + #include <sys/un.h> +/*#endif*/ +#include <unistd.h> + +volatile sig_atomic_t sig_flag = 0; + +/* TODO: call write() once; check for its errors */ +static void sig_handler(int signo) { + char *sig_name = strsignal(signo); + char *sig_msg = " signal is caught\n"; + write(STDOUT_FILENO, sig_name, strlen(sig_name)); + write(STDOUT_FILENO, sig_msg, strlen(sig_msg)); + sig_flag = 1; +} + +void *process(void *arg) { + int client_fd = *((int *)arg); + char *buf = malloc(sizeof(acccre_size_t)); + + /* TODO: make a protocol */ + while (sig_flag == 0) { + if (recv(client_fd, buf, sizeof(acccre_size_t), 0) > 0) { + /* Now, parse the request... */ + acccre_size_t msg_len = *buf; + printf("size of message is %d\n", (acccre_size_t)msg_len); + + buf = realloc(buf, msg_len); + recv(client_fd, buf, msg_len, 0); + char *msg = buf; + printf("%s\n", msg); + + /* ... + char *response = (char *)malloc(BUFFER_SIZE * sizeof(char)); + snprintf(response, BUFFER_SIZE, + ""); + size_t response_len;*/ + /* ... */ + } + } + + close(client_fd); + free(arg); + free(buf); + + return 0; +} + +int main (int argc, char *argv[]) { + struct sigaction sa = { + sig_handler, /* sa_handler */ + 0, /* sa_mask */ + 0 /* sa_flags */ + }; + for (int i = 0; sigs[i] != SIGXFSZ; i++) { + if (sigaction(sigs[i], &sa, NULL) != 0) { + perror("sigaction()"); + exit(EXIT_FAILURE); + } + } + + int server_fd; + if ((server_fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { + perror("socket()"); + exit(EXIT_FAILURE); + } + + struct sockaddr_un sun = { + AF_UNIX, /* sun_family */ + DEFAULT_PATH /* sun_path */ + }; + if (argc > 1) { + /* Taken from https://pubs.opengroup.org/onlinepubs/9799919799/ */ + if (sizeof(argv[1]) >= sizeof(((struct sockaddr_un *)0)->sun_path)) { + strcpy(sun.sun_path, argv[1]); + } + else { + fprintf(stderr, "Path to the socket is longer than %zu.\n", sizeof(((struct sockaddr_un *)0)->sun_path)); + exit(EXIT_FAILURE); + } + } + + if (bind(server_fd, (struct sockaddr *)&sun, sizeof(sun)) != 0) { + perror("bind()"); + exit(EXIT_FAILURE); + } + + if (listen(server_fd, 5) != 0) { + perror("listen()"); + exit(EXIT_FAILURE); + } + + puts("Ready!"); + + while (sig_flag == 0) { + struct sockaddr_un client_addr; + socklen_t client_addr_len = sizeof(client_addr); + + int *client_fd = malloc(sizeof(int)); + + *client_fd = accept(server_fd, (struct sockaddr *)&client_addr, &client_addr_len); + if (*client_fd == -1) { + perror("accept()"); + free(client_fd); + continue; + } + + pthread_t thread_id; /* TODO */ + pthread_create(&thread_id, NULL, process, (void *)client_fd); + pthread_detach(thread_id); + } + + close(server_fd); + unlink(sun.sun_path); + return 0; +} +#endif diff --git a/acccre-server.h b/acccre-server.h new file mode 100644 index 0000000..7ffd84b --- /dev/null +++ b/acccre-server.h @@ -0,0 +1,25 @@ +#include <signal.h> +#include <stdint.h> + +const int sigs[] = { + SIGABRT, + SIGALRM, + SIGFPE, + SIGHUP, + SIGILL, + SIGINT, + SIGPIPE, + SIGQUIT, + SIGSEGV, + SIGSYS, + SIGTERM, + SIGTRAP, + SIGTSTP, + SIGVTALRM, + SIGXCPU, + SIGXFSZ +}; + +#define BUFFER_SIZE 100 +#define DEFAULT_PATH "./acccre.sock" +typedef uint16_t acccre_size_t; diff --git a/client.py b/client.py new file mode 100755 index 0000000..26548c2 --- /dev/null +++ b/client.py @@ -0,0 +1,27 @@ +#!/usr/bin/env python3 +from ctypes import c_uint16 as acccre_size +from socket import * +from sys import * + +sun = socket(AF_UNIX) +if len(argv) >= 2 and argv[1]: + sun_path = argv[1] +else: + sun_path = "./acccre.sock" + +try: + sun.connect(sun_path) +except FileNotFoundError as e: + exit(e) + +if len(argv) >= 3 and argv[2]: + msg = argv[2].encode("ascii") +else: + msg = b"hello, world!" + +# 1 char in Python is 2 bytes instead of 1 byte in C +#msg_len = acccre_size(getsizeof(msg)) +msg_len = acccre_size(2) +sun.send(msg_len) +sun.send(msg) +sun.close |