Last active
September 1, 2025 00:25
-
-
Save reterVision/8300781 to your computer and use it in GitHub Desktop.
Revisions
-
reterVision revised this gist
Jan 7, 2014 . 1 changed file with 249 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1 +1,249 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <netdb.h> #include <unistd.h> #include <fcntl.h> #include <sys/epoll.h> #include <errno.h> #define MAXEVENTS 64 static int make_socket_non_blocking(int sfd) { int flags, s; flags = fcntl(sfd, F_GETFL, 0); if(flags == -1) { perror("fcntl"); return -1; } flags |= O_NONBLOCK; s = fcntl(sfd, F_SETFL, flags); if(s == -1) { perror("fcntl"); return -1; } return 0; } static int create_and_bind(char *port) { struct addrinfo hints; struct addrinfo *result, *rp; int s, sfd; memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_PASSIVE; s = getaddrinfo(NULL, port, &hints, &result); if(s != 0) { fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(s)); return -1; } for(rp=result;rp!=NULL;rp=rp->ai_next) { sfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); if(sfd == -1) { continue; } s = bind(sfd, rp->ai_addr, rp->ai_addrlen); if(s == 0) { break; } close(sfd); } if(rp == NULL) { fprintf(stderr, "Could not bind\n"); return -1; } freeaddrinfo(result); return sfd; } int main(int argc, char *argv[]) { int sfd, s; int efd; struct epoll_event event; struct epoll_event *events; if(argc != 2) { fprintf(stderr, "Usage: %s [port]\n", argv[0]); exit(EXIT_FAILURE); } sfd = create_and_bind(argv[1]); if(sfd == -1) abort(); s = make_socket_non_blocking(sfd); if(s == -1) abort(); s = listen(sfd, SOMAXCONN); if(s == -1) { perror("listen"); abort(); } efd = epoll_create1(0); if(efd == -1) { perror("epoll_create"); abort(); } event.data.fd = sfd; event.events = EPOLLIN | EPOLLET; s = epoll_ctl(efd, EPOLL_CTL_ADD, sfd, &event); if(s == -1) { perror("epoll_ctl"); abort(); } /* Buffer where events are returned */ events = calloc(MAXEVENTS, sizeof(event)); /* event loop */ while(1) { int n, i; fprintf(stdout, "Blocking and waiting for epoll event...\n"); n = epoll_wait(efd, events, MAXEVENTS, -1); fprintf(stdout, "Received epoll event\n"); for(i=0; i<n; i++) { if((events[i].events & EPOLLERR) || (events[i].events & EPOLLHUP) || (!(events[i].events & EPOLLIN))) { fprintf(stderr, "epoll error\n"); close(events[i].data.fd); continue; } else if(sfd == events[i].data.fd) { while(1) { struct sockaddr in_addr; socklen_t in_len; int infd; char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV]; in_len = sizeof(in_addr); infd = accept(sfd, &in_addr, &in_len); if(infd == -1) { if((errno == EAGAIN) || (errno == EWOULDBLOCK)) { break; } else { perror("accept"); break; } } s = getnameinfo(&in_addr, in_len, hbuf, sizeof(hbuf), sbuf, sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV); if(s == 0) { printf("Accepted connection on descriptor %d" "(host=%s, port=%s)\n", infd, hbuf, sbuf); } s = make_socket_non_blocking(infd); if(s == -1) abort(); event.data.fd = infd; event.events = EPOLLIN | EPOLLET; s = epoll_ctl(efd, EPOLL_CTL_ADD, infd, &event); if(s == -1) { perror("epoll_ctl"); abort(); } } continue; } else { int done = 0; while(1) { ssize_t count; char buf[512]; count = read(events[i].data.fd, buf, sizeof(buf)); if(count == -1) { if(errno != EAGAIN) { perror("read"); done =1; } break; } else if(count == 0) { done = 1; break; } buf[count] = '\n'; s = write(1, buf, count+1); if(s == -1) { perror("write"); abort(); } s = write(events[i].data.fd, buf, count+1); if(s == -1) { perror("socket write"); abort(); } } if(done) { printf("Closed connection on descriptor %d\n", events[i].data.fd); close(events[i].data.fd); } } } } free(events); close(sfd); return EXIT_SUCCESS; } -
reterVision created this gist
Jan 7, 2014 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1 @@ test