Skip to content

Instantly share code, notes, and snippets.

@joastbg
Created August 11, 2016 16:06
Show Gist options
  • Save joastbg/ffb60b1e1a513511538b912c09cfda43 to your computer and use it in GitHub Desktop.
Save joastbg/ffb60b1e1a513511538b912c09cfda43 to your computer and use it in GitHub Desktop.
Epoll + Lua
#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