hermes

HTTP GET/HEAD-only web server for static content.
git clone https://git.francescosaccone.com/hermes
Log | Files | Refs | README | LICENSE

socket.c (2522B)


      1 #include <arpa/inet.h>
      2 #include <errno.h>
      3 #include <stdio.h>
      4 #include <stdlib.h>
      5 #include <string.h>
      6 #include <sys/ioctl.h>
      7 #include <sys/socket.h>
      8 #include <unistd.h>
      9 
     10 #include "socket.h"
     11 #include "utils.h"
     12 
     13 int
     14 create_socket(unsigned int port) {
     15 	int socket_fd = socket(AF_INET, SOCK_STREAM, 0),
     16 	    yes = 1;
     17 	struct sockaddr_in address;
     18 
     19 	if (socket_fd == -1) {
     20 		print_error("error: create socket: %s",
     21 		            strerror(errno));
     22 		return -1;
     23 	}
     24 
     25 	if (setsockopt(socket_fd,
     26 	               SOL_SOCKET,
     27 	               SO_REUSEADDR,
     28 	               &yes,
     29 	               sizeof(yes)) == -1) {
     30 		print_error("error: set SO_REUSEADDR to socket: %s",
     31 		            strerror(errno));
     32 	}
     33 
     34 	memset(&address, 0, sizeof(address));
     35 	address.sin_family = AF_INET;
     36 	address.sin_addr.s_addr = INADDR_ANY;
     37 	address.sin_port = htons(port);
     38 
     39 	if (bind(socket_fd,
     40 	         (struct sockaddr *)&address,
     41 	         sizeof(address)) == -1) {
     42 		print_error("error: bind socket to address: %s",
     43 		            strerror(errno));
     44 		return -1;
     45 	}
     46 
     47 	if (listen(socket_fd, 3) == -1) {
     48 		print_error("error: listen on socket: %s",
     49 		            strerror(errno));
     50 		close(socket_fd);
     51 		return -1;
     52 	}
     53 
     54 	return socket_fd;
     55 }
     56 
     57 void
     58 close_socket(int socket_fd) {
     59 	close(socket_fd);
     60 }
     61 
     62 int
     63 get_socket_size(int socket_fd) {
     64 	int result;
     65 
     66 	if (ioctl(socket_fd, FIONREAD, &result) == -1) {
     67 		return -1;
     68 	};
     69 
     70 	return result;
     71 }
     72 
     73 int
     74 accept_client(int server_socket_fd) {
     75 	struct sockaddr_in client_address;
     76 	socklen_t client_address_length = sizeof(client_address);
     77 	int client_socket_fd = accept(server_socket_fd,
     78 	                              (struct sockaddr *)&client_address,
     79 	                              &client_address_length);
     80 
     81 	return client_socket_fd;
     82 }
     83 
     84 int
     85 read_client_request(int client_socket_fd,
     86                     char *buffer,
     87                     unsigned int buffer_size) {
     88 	ssize_t bytes_received;
     89 
     90 	if (buffer == NULL || buffer_size == 0) {
     91 		print_error("error: invalid buffer provided in "
     92 		            "read_client_request");
     93 		return -1;
     94 	}
     95 
     96 	memset(buffer, 0, buffer_size);
     97 
     98 	bytes_received = recv(client_socket_fd,
     99 	                      buffer,
    100 	                      buffer_size - 1,
    101 	                      0);
    102 
    103 	if (bytes_received <= 0) {
    104 		return -1;
    105 	}
    106 
    107 	if (bytes_received < buffer_size) {
    108 		buffer[bytes_received] = '\0';
    109 	} else {
    110 		buffer[buffer_size - 1] = '\0';
    111 	}
    112 
    113 	return 0;
    114 }
    115 
    116 int
    117 send_to_socket(int socket_fd, char *data) {
    118 	if (send(socket_fd, data, strlen(data), 0) == -1) {
    119 		return -1;
    120 	}
    121 
    122 	return 0;
    123 }