#define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include #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 ()); }