#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; } static const int nfds = 50; // TODO-maybe: Expand, allow setting default starting value? struct pollfd fds[nfds]; struct connection * data[nfds]; for (int i = 0; i < nfds; ++i) { fds[i].fd = -1; fds[i].events = POLLIN; // TODO: Handle yielded writes data[i] = NULL; } const int server = open_server(NULL, service); if (-1 == server) return 4; fds[0].fd = server; fds[0].events = POLLIN; plop.fds = fds; plop.data = data; plop.nfds = nfds; while (1) { int ret = poll(fds, nfds, -1); // TODO-maybe: Specify timeout and allow timers? if (-1 == ret) return 5; for (int i = 0; i < nfds; ++i) { if (-1 == fds[i].fd || 0 == fds[i].revents) continue; if (NULL == data[i]) { if (-1 == plop_handle_server(server)) return 6; } else { ret = plop_handle_client(data[i]); if (-1 == ret) return 7; else if (0 == ret) fds[i].fd = -1; } } } }