aboutsummaryrefslogtreecommitdiff
path: root/src/server.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/server.c')
-rw-r--r--src/server.c79
1 files changed, 71 insertions, 8 deletions
diff --git a/src/server.c b/src/server.c
index 6c0a7a2..6c32a85 100644
--- a/src/server.c
+++ b/src/server.c
@@ -5,6 +5,18 @@
#include <assert.h>
#include "server.h"
+#include "socket.h"
+#include "log.h"
+
+typedef struct client_thread_args {
+ int client_fd;
+ server_ctx *server_ctx;
+} client_thread_args;
+
+static int server_accept_client(const server_ctx ctx[],
+ size_t siz, struct epoll_event *event);
+static void *
+client_mainloop_epoll(void *arg);
server_ctx *
@@ -31,7 +43,7 @@ int server_validate_ctx(const server_ctx *ctx)
return 0;
}
-int server_setup_epoll(const server_ctx *ctx[], size_t siz)
+int server_setup_epoll(const server_ctx ctx[], size_t siz)
{
int s;
int fd = epoll_create1(0); /* flags == 0 -> obsolete size arg is dropped */
@@ -42,35 +54,86 @@ int server_setup_epoll(const server_ctx *ctx[], size_t siz)
if (fd < 0)
return -1;
- for (int i = 0; i < siz; ++i) {
+ for (size_t i = 0; i < siz; ++i) {
memset(&ev, 0, sizeof(ev));
- ev.data.fd = ctx[i]->sock.fd;
+ ev.data.fd = ctx[i].sock.fd;
ev.events = EPOLLIN | EPOLLET;
- s = epoll_ctl(fd, EPOLL_CTL_ADD, ctx[i]->sock.fd, &ev);
+ s = epoll_ctl(fd, EPOLL_CTL_ADD, ctx[i].sock.fd, &ev);
if (s) {
close(fd);
- return -1;
+ return -2;
}
}
return fd;
}
-int server_mainloop_epoll(int epoll_fd, const server_ctx *ctx[], size_t siz)
+int server_mainloop_epoll(int epoll_fd, const server_ctx ctx[], size_t siz)
{
- struct epoll_event *events = calloc(POTD_MAXEVENTS, sizeof(*events));
+ static struct epoll_event *events = NULL;
+
+ if (!events)
+ events = (struct epoll_event *) calloc(POTD_MAXEVENTS, sizeof(*events));
assert(events);
assert(ctx);
assert(siz > 0 && siz < POTD_MAXFD);
while (1) {
- int n;
+ int n, i;
n = epoll_wait(epoll_fd, events, POTD_MAXEVENTS, -1);
+ if (n < 0)
+ return 1;
+
+ for (i = 0; i < n; ++i) {
+ if ((events[i].events & EPOLLERR) ||
+ (events[i].events & EPOLLHUP) ||
+ (!(events[i].events & EPOLLIN)))
+ {
+ E("Epoll for descriptor %d failed", events[i].data.fd);
+ E_STRERR("epoll_wait");
+ close(events[i].data.fd);
+ continue;
+ } else {
+ if (server_accept_client(ctx, siz, &events[i])) {
+ /* new client connection, accept succeeded */
+ continue;
+ }
+ D2("FD: %d/%lu , %d", events[i].data.fd, siz, n);
+ }
+ }
}
free(events);
return 0;
}
+
+static int server_accept_client(const server_ctx ctx[],
+ size_t siz, struct epoll_event *event)
+{
+ size_t i;
+ int client_fd;
+ struct sockaddr_in clientaddr;
+
+ for (i = 0; i < siz; ++i) {
+ if (ctx[i].sock.fd == event->data.fd) {
+ client_fd = socket_accept_in(&ctx[i].sock, &clientaddr);
+ if (client_fd < 0) {
+ E_STRERR("Could not accept client connection");
+ } else {
+ return 1;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static void *
+client_mainloop_epoll(void *arg)
+{
+ (void) arg;
+ return NULL;
+}