summaryrefslogtreecommitdiffstats
path: root/cc_const.cc
blob: 85e9ec7bd12cef26574542ff5210584a75c1679e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#define _GNU_SOURCE

#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <aio.h>

#include <sys/socket.h>
#include <sys/epoll.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/epoll.h>
#include <jemalloc/jemalloc.h>

#include <string>

#include "log.h"

#define PORT 8080
#define LISTEN_N 50
#define EVENTS_N 50

void die (const char *msg) {
    (void)msg;
    log_error ("  %s", msg);
    log_error ("  %s", strerror (errno));
    exit (EXIT_FAILURE);
}


#define assertfd(FD) if (FD < 0) die (#FD " is not a valid file descriptor")
#define assert(EX) if (!(EX)) die (#EX " is false")

std::string resp =
    "HTTP/1.1 200 OK\r\n"
    "Content-Length: 25\r\n"
    "Content-Type: text/html\r\n"
    "Connection: close\r\n"
    "\r\n"
    "Hello from const server\r\n";

void dostuff (int sock);

int main () {

    int sockfd, newsockfd;
    unsigned clilen;
    struct sockaddr_in serv_addr, cli_addr;
    log_set_level (LOG_INFO);


    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    assertfd (sockfd);
    int enable = 1;
    assert (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int)) >= 0);

    bzero((char *) &serv_addr, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = INADDR_ANY;
    serv_addr.sin_port = htons(PORT);

    assert (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) >= 0);

    struct epoll_event ev, events[EVENTS_N];
    int epollfd = epoll_create1 (0);
    ev.data.ptr = NULL;
    ev.events = EPOLLIN | EPOLLERR;
    assert (epoll_ctl (epollfd, EPOLL_CTL_ADD, sockfd, &ev) == 0);

    listen(sockfd, LISTEN_N);
    clilen = sizeof(cli_addr);
    for (;;) {
        /*int nfds = epoll_wait (epollfd, events, EVENTS_N, 3000);
        if (nfds == 0) {
            exit (EXIT_SUCCESS);
        }
        assert (nfds != -1);
        log_trace ("nfds: %d", nfds);
        for (int i = 0; i < nfds; ++i) {*/
        for (;;) {            //if (events[i].data.ptr == NULL) {
                newsockfd = accept4(sockfd, (struct sockaddr *) &cli_addr, &clilen, SOCK_NONBLOCK);
                assertfd (newsockfd);
                log_trace ("new: %d", newsockfd);

                dostuff (newsockfd);
            //}
            //else {
            //    die ("pffff");
            //}
        }
    }
    return 0;
}

ssize_t write_sock (int sock);

void dostuff (int sock) {
    write_sock (sock);
    close (sock);
}

inline ssize_t write_sock (int sock) {
    
    return write (sock, resp.c_str (), resp.size ());
}