commit 90588913d43818c0c3ad6e23eaf7a0fedf98e3f5
parent ba2ed8d954143cb55ba8cb845a5f4a5ee3383249
Author: Joris Vink <joris@coders.se>
Date: Fri, 3 May 2013 00:04:06 +0200
allow sending SIGHUP to kore, which will then reload its content module
Diffstat:
3 files changed, 51 insertions(+), 5 deletions(-)
diff --git a/includes/kore.h b/includes/kore.h
@@ -91,7 +91,8 @@ struct connection {
struct kore_module_handle {
char *uri;
char *domain;
- void *func;
+ char *func;
+ void *addr;
int type;
TAILQ_ENTRY(kore_module_handle) list;
@@ -122,6 +123,7 @@ int kore_split_string(char *, char *, char **, size_t);
long long kore_strtonum(const char *, long long, long long, int *);
void kore_module_load(char *);
+void kore_module_reload(void);
int kore_module_loaded(void);
void *kore_module_handler_find(char *, char *);
int kore_module_handler_new(char *, char *, char *, int);
diff --git a/src/kore.c b/src/kore.c
@@ -28,6 +28,7 @@
#include <errno.h>
#include <fcntl.h>
+#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -44,11 +45,13 @@
static int efd = -1;
static SSL_CTX *ssl_ctx = NULL;
+volatile sig_atomic_t sig_recv;
static TAILQ_HEAD(, connection) disconnected;
int server_port = 0;
char *server_ip = NULL;
+static void kore_signal(int);
static int kore_socket_nonblock(int);
static int kore_server_sslstart(void);
static void kore_event(int, int, void *);
@@ -86,12 +89,23 @@ main(int argc, char *argv[])
http_init();
TAILQ_INIT(&disconnected);
+ sig_recv = 0;
+ signal(SIGHUP, kore_signal);
+
kore_event(server.fd, EPOLLIN, &server);
events = kore_calloc(EPOLL_EVENTS, sizeof(struct epoll_event));
for (;;) {
+ if (sig_recv == SIGHUP) {
+ kore_module_reload();
+ sig_recv = 0;
+ }
+
n = epoll_wait(efd, events, EPOLL_EVENTS, 10);
- if (n == -1)
+ if (n == -1) {
+ if (errno == EINTR)
+ continue;
fatal("epoll_wait(): %s", errno_s);
+ }
if (n > 0)
kore_log("main(): %d sockets available", n);
@@ -422,3 +436,9 @@ kore_event(int fd, int flags, void *udata)
}
}
}
+
+static void
+kore_signal(int sig)
+{
+ sig_recv = sig;
+}
diff --git a/src/module.c b/src/module.c
@@ -40,6 +40,7 @@
#include "kore.h"
static void *mod_handle = NULL;
+static char *mod_name = NULL;
static time_t mod_last_mtime = 0;
static TAILQ_HEAD(, kore_module_handle) handlers;
@@ -63,6 +64,28 @@ kore_module_load(char *module_name)
fatal("%s", dlerror());
TAILQ_INIT(&handlers);
+ mod_name = kore_strdup(module_name);
+}
+
+void
+kore_module_reload(void)
+{
+ struct kore_module_handle *hdlr;
+
+ if (dlclose(mod_handle))
+ fatal("cannot close existing module: %s", dlerror());
+
+ mod_handle = dlopen(mod_name, RTLD_NOW);
+ if (mod_handle == NULL)
+ fatal("kore_module_reload(): %s", dlerror());
+
+ TAILQ_FOREACH(hdlr, &handlers, list) {
+ hdlr->addr = dlsym(mod_handle, hdlr->func);
+ if (hdlr->func == NULL)
+ fatal("no function '%s' found", hdlr->func);
+ }
+
+ kore_log("reloaded '%s' module", mod_name);
}
int
@@ -90,9 +113,10 @@ kore_module_handler_new(char *path, char *domain, char *func, int type)
snprintf(uri, sizeof(uri), "%s%s", domain, path);
hdlr = (struct kore_module_handle *)kore_malloc(sizeof(*hdlr));
- hdlr->func = addr;
+ hdlr->addr = addr;
hdlr->type = type;
hdlr->uri = kore_strdup(uri);
+ hdlr->func = kore_strdup(func);
TAILQ_INSERT_TAIL(&(handlers), hdlr, list);
return (KORE_RESULT_OK);
@@ -109,9 +133,9 @@ kore_module_handler_find(char *domain, char *path)
TAILQ_FOREACH(hdlr, &handlers, list) {
if (hdlr->uri[0] != '.' && !strcmp(hdlr->uri, uri))
- return (hdlr->func);
+ return (hdlr->addr);
if (p != NULL && hdlr->uri[0] == '.' && !strcmp(hdlr->uri, p))
- return (hdlr->func);
+ return (hdlr->addr);
}
return (NULL);