aboutsummaryrefslogtreecommitdiff
path: root/src/disp.c
diff options
context:
space:
mode:
authorTristan Riehs <tristan.riehs@bordeaux-inp.fr>2024-06-30 16:20:34 +0900
committerTristan Riehs <tristan.riehs@bordeaux-inp.fr>2024-06-30 16:20:34 +0900
commit46e6de294243e8dc593551bfe8c0e7090d03a159 (patch)
treea898e2c4504c8da30fdea2aebf034f7edb0e7a3e /src/disp.c
parent5d5ff4076abe2e8aeb40980ec1b3ef9ee5fa92e6 (diff)
Improve dynamic loading
Make loading code cleaner and prefix public function names to allow static compilation.
Diffstat (limited to 'src/disp.c')
-rw-r--r--src/disp.c81
1 files changed, 47 insertions, 34 deletions
diff --git a/src/disp.c b/src/disp.c
index c0294fe..8a1a174 100644
--- a/src/disp.c
+++ b/src/disp.c
@@ -25,17 +25,30 @@
#include "disp.h"
-#define dlsym_and_check(dest, name) \
- dest->name = dlsym(dest->dl_handle, #name); \
- if ((!dest->name) || (dest->name == dest->dl_handle)) { \
- char *msg = dlerror(); \
- fprintf(stderr, "calculer: %s\n", msg); \
- dlclose(dest->dl_handle); \
- free(dest); \
- return -1; \
+static void *
+load_generic_symbol(struct disp *disp, char *base_name)
+{
+ char full_name[64] = {0};
+ void *ptr;
+
+ strcpy(full_name, disp->name);
+ strcat(full_name, "_");
+ strcat(full_name, base_name);
+
+ ptr = dlsym(disp->dl_handle, full_name);
+
+ if (!ptr)
+ {
+ fprintf(stderr, "calculer: %s\n", dlerror());
+ destroy_disp(disp);
+ exit(1);
}
-static int
+ return ptr;
+}
+
+
+static void
load_symbols(struct disp *disp)
{
void *handle = dlopen(disp->so_path, RTLD_LAZY);
@@ -43,24 +56,21 @@ load_symbols(struct disp *disp)
if (!handle)
{
fprintf(stderr, "calculer: %s\n", dlerror());
+ destroy_disp(disp);
exit(1);
}
-#ifndef NDEBUG
- printf("INFO: successfully loaded symbols from \"%s\"\n", disp->so_path);
-#endif
+ disp->dl_handle = handle;
+ disp->init = load_generic_symbol(disp, "init");
+ disp->display_calc = load_generic_symbol(disp, "display_calc");
+ disp->read_input = load_generic_symbol(disp, "read_input");
+ disp->display_res = load_generic_symbol(disp, "display_res");
+ disp->destroy = load_generic_symbol(disp, "destroy");
+ disp->pre_reload = load_generic_symbol(disp, "pre_reload");
+ disp->post_reload = load_generic_symbol(disp, "post_reload");
- disp->dl_handle = handle;
- dlsym_and_check(disp, init);
- dlsym_and_check(disp, display_calc);
- dlsym_and_check(disp, read_input);
- dlsym_and_check(disp, display_res);
- dlsym_and_check(disp, destroy);
-#ifndef NDEBUG
- dlsym_and_check(disp, pre_reload);
- dlsym_and_check(disp, post_reload);
-#endif
- return 0;
+ printf("INFO: successfully loaded symbols from \"%s\"\n",
+ disp->so_path);
}
struct disp *
@@ -74,8 +84,11 @@ get_disp(char *disp_name)
strcat(so_path, ".so.0.0.0");
struct disp *disp = malloc(sizeof(*disp));
disp->so_path = strdup(so_path);
+ disp->name = disp_name;
+
+ load_symbols(disp);
- return load_symbols(disp) == 0 ? disp : NULL;
+ return disp;
#else
# error "not available yet"
#endif
@@ -85,8 +98,12 @@ get_disp(char *disp_name)
void
destroy_disp(struct disp *disp)
{
- disp->destroy();
- dlclose(disp->dl_handle);
+ if (disp->destroy)
+ disp->destroy();
+
+ if (disp->dl_handle)
+ dlclose(disp->dl_handle);
+
free(disp->so_path);
free(disp);
}
@@ -95,22 +112,18 @@ destroy_disp(struct disp *disp)
void
disp_reload(struct disp *disp)
{
- int status;
printf("INFO: saving state\n");
void *state = disp->pre_reload();
+
printf("INFO: closing shared library\n");
dlclose(disp->dl_handle);
- printf("INFO: reloading symbols\n");
- status = load_symbols(disp);
- if (status == -1)
- {
- printf("calculer: %s\n", dlerror());
- exit(1);
- }
+ printf("INFO: reloading symbols\n");
+ load_symbols(disp);
printf("INFO: loading state\n");
disp->post_reload(state);
+
printf("INFO: reloading done\n");
}
#endif