Created
August 11, 2016 16:06
-
-
Save joastbg/ffb60b1e1a513511538b912c09cfda43 to your computer and use it in GitHub Desktop.
Epoll + Lua
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 characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <errno.h> | |
#include <string.h> | |
#include <unistd.h> | |
#include <fcntl.h> | |
#include <sys/types.h> | |
#include <arpa/inet.h> | |
#include <netinet/in.h> | |
#include <sys/socket.h> | |
#include <sys/epoll.h> | |
#include <sys/wait.h> | |
#include <lua.h> | |
#include <lauxlib.h> | |
#include <lualib.h> | |
#include <math.h> | |
#define MAX_EVENTS 10 | |
#define PORT 9136 | |
const char str[] = | |
"HTTP/1.1 200 OK\r\nDate: Mon, 23 May 2005 22:38:34 GMT\r\nContent-Type: application/json; charset=UTF-8\r\nContent-Encoding: UTF-8\r\nContent-Length: 28\r\nLast-Modified: Wed, 08 Jan 2003 23:11:55 GMT\r\nServer: Apache/1.3.3.7 (Unix) (Red-Hat/Linux)\r\nETag: \"3f80f-1b6-3e1cb03b\"\r\nAccept-Ranges: bytes\r\nConnection: close\r\n\r\n"; | |
unsigned int req_seqnr = 0; | |
lua_State *L; | |
int execlua(char* ret) { | |
char buff[256]; | |
int error; | |
//lua_State *L; | |
//L = luaL_newstate(); | |
//luaL_openlibs(L); | |
sprintf(buff, "%s", "JSON = (loadfile \"JSON.lua\")() -- one-time load of the routines\nlocal raw_json_text = '{\"name\":\"johan\"}'\nlocal T = JSON:decode(raw_json_text) -- decode example\nT.id=1001\nprint(JSON:encode(T))\nstr = JSON:encode(T)\n"); | |
error = luaL_loadbuffer(L, buff, strlen(buff), "line") || lua_pcall(L, 0, 0, 0); | |
if (error) { | |
fprintf(stderr, "!! %s", lua_tostring(L, -1)); | |
lua_pop(L, 1); /* pop error message from the stack */ | |
} | |
lua_getglobal(L, "str"); | |
const char *s = lua_tostring(L, -1); /* any Lua string */ | |
//size_t l = lua_strlen(L, -1); /* its length */ | |
sprintf(ret, "%s", s); | |
/* | |
while (fgets(buff, sizeof(buff), stdin) != NULL) { | |
error = luaL_loadbuffer(L, buff, strlen(buff), "line") || lua_pcall(L, 0, 0, 0); | |
if (error) { | |
fprintf(stderr, "!! %s", lua_tostring(L, -1)); | |
lua_pop(L, 1); | |
} | |
}*/ | |
//lua_close(L); | |
} | |
/* | |
JSON: https://tools.ietf.org/html/rfc7159 | |
*/ | |
void setnonblocking(int sock) | |
{ | |
int opts; | |
opts = fcntl(sock, F_GETFL); | |
if (opts < 0) { | |
perror("fcntl(sock,GETFL)"); | |
exit(1); | |
} | |
opts = opts | O_NONBLOCK; | |
if (fcntl(sock, F_SETFL, opts) < 0) { | |
perror("fcntl(sock,SETFL,opts)"); | |
exit(1); | |
} | |
} | |
void do_use_fd(int client_fd) | |
{ | |
char buffer[1024]; | |
int len; | |
if ((len = read(client_fd, buffer, 1024)) == -1) { | |
perror("read"); | |
} | |
buffer[len] = 0; | |
printf("#%d: Received:\n%s\n\n", ++req_seqnr, buffer); | |
char luabuffer[1024]; | |
char repstr[1024]; | |
execlua(luabuffer); | |
printf("--------\n%s\n----------\n", luabuffer); | |
sprintf(repstr, "%s%s\r\n", str, luabuffer); | |
printf("--------\n%s\n----------\n", repstr); | |
if (send(client_fd, repstr, strlen(repstr), 0) == -1) { | |
perror("send"); | |
} | |
close(client_fd); | |
} | |
int main(int argc, char **argv) | |
{ | |
L = luaL_newstate(); | |
luaL_openlibs(L); | |
struct sockaddr_in serv; | |
struct sockaddr_in addr; | |
memset(&serv, 0, sizeof(serv)); | |
serv.sin_family = AF_INET; | |
serv.sin_addr.s_addr = htonl(INADDR_ANY); | |
serv.sin_port = htons(PORT); | |
int sockfd = socket(AF_INET, SOCK_STREAM, 0); | |
int addrlen = 0; | |
bind(sockfd, (struct sockaddr *) &serv, sizeof(struct sockaddr)); | |
listen(sockfd, 1); | |
struct epoll_event ev, events[MAX_EVENTS]; | |
int listen_sock, conn_sock, nfds, epollfd, n; | |
epollfd = epoll_create1(0); | |
if (epollfd == -1) { | |
perror("epoll_create1"); | |
exit(EXIT_FAILURE); | |
} | |
listen_sock = sockfd; | |
ev.events = EPOLLIN; | |
ev.data.fd = listen_sock; | |
if (epoll_ctl(epollfd, EPOLL_CTL_ADD, listen_sock, &ev) == -1) { | |
perror("epoll_ctl: listen_sock"); | |
exit(EXIT_FAILURE); | |
} | |
for (;;) { | |
nfds = epoll_wait(epollfd, events, MAX_EVENTS, -1); | |
if (nfds == -1) { | |
perror("epoll_wait"); | |
exit(EXIT_FAILURE); | |
} | |
for (n = 0; n < nfds; ++n) { | |
if (events[n].data.fd == listen_sock) { | |
conn_sock = accept(listen_sock, (struct sockaddr *) &addr, &addrlen); | |
if (conn_sock == -1) { | |
perror("accept"); | |
exit(EXIT_FAILURE); | |
} | |
setnonblocking(conn_sock); | |
ev.events = EPOLLIN | EPOLLET; | |
ev.data.fd = conn_sock; | |
if (epoll_ctl(epollfd, EPOLL_CTL_ADD, conn_sock, &ev) == -1) { | |
perror("epoll_ctl: conn_sock"); | |
exit(EXIT_FAILURE); | |
} | |
} else { | |
do_use_fd(events[n].data.fd); | |
} | |
} | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment