A small http server written in C
git clone git://git.janzachar.dev/shttp.git
0#include "super.h"12#include <arpa/inet.h>3#include <pthread.h>4#include <unistd.h>5#include <signal.h>6#include <string.h>7#include <stdlib.h>8#include <stdio.h>910#define serror(sock, err) { \11 perror((err)); \12 close((sock)->fd); \13 exit(EXIT_FAILURE); \14}151617void sock_fill(struct sock *sock, const char *addr, int port)18{19 memset(sock, 0, sizeof(*sock));20 sock->len = sizeof(sock->addr);2122 sock->addr.sin_family = AF_INET;23 sock->addr.sin_port = htons(port);2425 switch (inet_pton(AF_INET, addr, &sock->addr.sin_addr)) {26 default: break;27 case 0:28 printe("Not a valid address '%s'!\n", addr);29 close(sock->fd);30 exit(EXIT_FAILURE);31 case -1:32 serror(sock, "inet_pton()");33 }34}353637void sock_open(struct sock *sock)38{39 sock->fd = socket(AF_INET, SOCK_STREAM, 0);4041 int opt = 1;42 if (setsockopt(sock->fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)))43 serror(sock, "setsockopt() reuse address");4445 if (bind(sock->fd, (struct sockaddr*)&sock->addr, sizeof(sock->addr)))46 serror(sock, "bind()");4748 if (listen(sock->fd, LISTEN_COUNT))49 serror(sock, "listen()");50}515253int _sock;54void sigint(int)55{56 close(_sock);57 _sock = 0;58}5960void sock_on(struct sock *sock, int (*func)(int))61{62 _sock = sock->fd;63 signal(SIGINT, sigint);6465 while (_sock) {66 int fd = accept(sock->fd, (struct sockaddr*)&sock->addr, &sock->len);67 if (!_sock) break;68 if (fd < 0)69 serror(sock, "accept()");7071 struct timeval timeout = {72 .tv_sec = 0,73 .tv_usec = 074 };7576 if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)))77 serror(sock, "setsockopt() receive timeout");7879 if (setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout)))80 serror(sock, "setsockopt() send timeout");8182 int out = func(fd);83 close(fd);84 if (out) break;85 }8687 if (_sock) close(_sock);88}8990