Fix memory leak

Signed-off-by: Jianhui Zhao <zhaojh329@gmail.com>
main
Jianhui Zhao 2020-10-06 17:56:01 +08:00
parent 99992538fa
commit 28c7e74aa8
5 changed files with 39 additions and 9 deletions

View File

@ -134,6 +134,8 @@ err:
srv->free(srv); srv->free(srv);
free(srv); free(srv);
ev_loop_destroy(loop);
return 0; return 0;
} }

View File

@ -335,8 +335,8 @@ static bool run_plugins(struct uh_connection *conn)
struct uh_str path = conn->get_path(conn); struct uh_str path = conn->get_path(conn);
while (p) { while (p) {
if (strlen(p->path) == path.len && !strncmp(path.p, p->path, path.len)) { if (strlen(p->h->path) == path.len && !strncmp(path.p, p->h->path, path.len)) {
p->handler(conn); p->h->handler(conn);
return true; return true;
} }
p = p->next; p = p->next;

View File

@ -31,7 +31,7 @@ static void test_handler(struct uh_connection *conn)
conn->chunk_end(conn); conn->chunk_end(conn);
} }
struct uh_plugin uh_plugin = { struct uh_plugin_handler uh_plugin_handler = {
.path = "/test", .path = "/test",
.handler = test_handler .handler = test_handler
}; };

View File

@ -42,6 +42,7 @@ void conn_free(struct uh_connection *conn);
static void uh_server_free(struct uh_server *srv) static void uh_server_free(struct uh_server *srv)
{ {
struct uh_connection *conn = srv->conns; struct uh_connection *conn = srv->conns;
struct uh_plugin *p = srv->plugins;
ev_io_stop(srv->loop, &srv->ior); ev_io_stop(srv->loop, &srv->ior);
@ -54,6 +55,16 @@ static void uh_server_free(struct uh_server *srv)
conn = next; conn = next;
} }
#ifdef HAVE_DLOPEN
while (p) {
struct uh_plugin *temp = p;
dlclose(p->dlh);
p = p->next;
free(temp);
break;
}
#endif
#if UHTTPD_SSL_SUPPORT #if UHTTPD_SSL_SUPPORT
uh_ssl_ctx_free(srv->ssl_ctx); uh_ssl_ctx_free(srv->ssl_ctx);
#endif #endif
@ -118,26 +129,38 @@ static int uh_server_ssl_init(struct uh_server *srv, const char *cert, const cha
static int uh_load_plugin(struct uh_server *srv, const char *path) static int uh_load_plugin(struct uh_server *srv, const char *path)
{ {
#ifdef HAVE_DLOPEN #ifdef HAVE_DLOPEN
struct uh_plugin_handler *h;
struct uh_plugin *p; struct uh_plugin *p;
void *dlh; void *dlh;
dlh = dlopen(path, RTLD_LAZY | RTLD_LOCAL); dlh = dlopen(path, RTLD_NOW | RTLD_LOCAL);
if (!dlh) { if (!dlh) {
uh_log_err("dlopen fail: %s\n", dlerror()); uh_log_err("dlopen fail: %s\n", dlerror());
return -1; return -1;
} }
p = dlsym(dlh, "uh_plugin"); h = dlsym(dlh, "uh_plugin_handler");
if (!p) { if (!h) {
uh_log_err("not found symbol 'uh_plugin'\n"); dlclose(dlh);
uh_log_err("not found symbol 'uh_plugin_handler'\n");
return -1; return -1;
} }
if (!p->path || !p->path[0] || !p->handler) { if (!h->path || !h->path[0] || !h->handler) {
dlclose(dlh);
uh_log_err("invalid plugin\n"); uh_log_err("invalid plugin\n");
return -1; return -1;
} }
p = calloc(1, sizeof(struct uh_plugin));
if (!p) {
uh_log_err("calloc: %s\n", strerror(errno));
return -1;
}
p->h = h;
p->dlh = dlh;
if (!srv->plugins) { if (!srv->plugins) {
srv->plugins = p; srv->plugins = p;
return 0; return 0;

View File

@ -31,9 +31,14 @@
#include "config.h" #include "config.h"
#include "log.h" #include "log.h"
struct uh_plugin { struct uh_plugin_handler {
const char *path; const char *path;
void (*handler)(struct uh_connection *conn); void (*handler)(struct uh_connection *conn);
};
struct uh_plugin {
struct uh_plugin_handler *h;
void *dlh;
struct uh_plugin *prev; struct uh_plugin *prev;
struct uh_plugin *next; struct uh_plugin *next;
}; };