#include #include #include #include #include "plop.h" /// Prints program usage to standard error. /// \param name Name of the executable from argv static void usage(const char * const name) { dprintf(2, "Usage: %s [-p PORT] [-h] [HANDLER]\n" "Starts plop server listening on PORT and serving HANDLER.\n" "HANDLER defaults to '" PLOP_DEFAULT_HANDLER "'.\n\n" " -p\tstart listening on PORT (default: 8080)\n" " -h\tprints this help message\n", name); } /// Standard entry point for the program. /// \param argc Argument count /// \param argv Argument array /// \return Error code int main(int argc, char ** argv) { const char * service = "8080"; int opt; while (-1 != (opt = getopt(argc, argv, "p:h"))) { switch (opt) { case 'p': { service = optarg; break; } case 'h': { usage(argv[0]); return 0; } default: { usage(argv[0]); return 1; // TODO: Extend error handling in main(). } } } if (optind < argc) { plop.handler = argv[optind]; } plop.L = plop_initialize_lua(); if (NULL == plop.L) { return 9; } if (LUA_OK != plop_load_handler(plop.L, plop.handler)) { return 2; } plop.efd = epoll_create1(0); if (-1 == plop.efd) { return 3; } struct epoll_event e; e.events = EPOLLIN; e.data.ptr = NULL; // TODO: Consider putting server's Lua state in here? const int server = open_server(NULL, service); // TODO: Check server's fd before ctl? if (-1 == epoll_ctl(plop.efd, EPOLL_CTL_ADD, server, &e)) { return 4; } static const int MAX_EVENTS = 20; struct epoll_event events[MAX_EVENTS]; while (1) { int evc = epoll_wait(plop.efd, events, MAX_EVENTS, -1); if (-1 == evc) { return 5; } for (int i = 0; i < evc; ++i) { if (NULL == events[i].data.ptr) { if (-1 == plop_handle_server(plop.L, plop.efd, server)) { return 6; } } else { struct connection * c = (struct connection *) events[i].data.ptr; if (-1 == plop_handle_client(plop.L, c)) { return 7; } } } } }