113 lines
2.7 KiB
C++
113 lines
2.7 KiB
C++
#include "hiisi.h"
|
|
|
|
#include <assert.h>
|
|
#include <atomic>
|
|
#include <dlfcn.h>
|
|
#include <link.h>
|
|
#include <signal.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
|
|
std::atomic<bool> reload_requested(false);
|
|
|
|
void reload_signal_handler(int) { reload_requested = true; }
|
|
|
|
Engine load_hiisi() {
|
|
const char *name = "build/hiisi/libhiisi-engine.so";
|
|
void *mod = dlopen(name, RTLD_NOW);
|
|
|
|
Lmid_t list;
|
|
dlinfo(mod, RTLD_DI_LMID, &list);
|
|
printf("link-map list id: %ld\n", list);
|
|
|
|
link_map *lmap = 0;
|
|
dlinfo(mod, RTLD_DI_LINKMAP, &lmap);
|
|
|
|
printf("Link map:\n");
|
|
printf("addr: %lu\n", lmap->l_addr);
|
|
printf("name: %s\n", lmap->l_name);
|
|
printf("dynamic section: %p\n", lmap->l_ld);
|
|
|
|
char pathname[256];
|
|
dlinfo(mod, RTLD_DI_ORIGIN, pathname);
|
|
printf("path: %s\n", pathname);
|
|
|
|
/* Discover the size of the buffer that we must pass to
|
|
RTLD_DI_SERINFO. */
|
|
Dl_serinfo serinfo;
|
|
Dl_serinfo *sip;
|
|
|
|
if (dlinfo(mod, RTLD_DI_SERINFOSIZE, &serinfo) == -1) {
|
|
fprintf(stderr, "RTLD_DI_SERINFOSIZE failed: %s\n", dlerror());
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
/* Allocate the buffer for use with RTLD_DI_SERINFO. */
|
|
|
|
sip = (Dl_serinfo *)malloc(serinfo.dls_size);
|
|
if (sip == NULL) {
|
|
perror("malloc");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
/* Initialize the 'dls_size' and 'dls_cnt' fields in the newly
|
|
allocated buffer. */
|
|
|
|
if (dlinfo(mod, RTLD_DI_SERINFOSIZE, sip) == -1) {
|
|
fprintf(stderr, "RTLD_DI_SERINFOSIZE failed: %s\n", dlerror());
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
/* Fetch and print library search list. */
|
|
|
|
if (dlinfo(mod, RTLD_DI_SERINFO, sip) == -1) {
|
|
fprintf(stderr, "RTLD_DI_SERINFO failed: %s\n", dlerror());
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
for (size_t j = 0; j < serinfo.dls_cnt; j++)
|
|
printf("dls_serpath[%zu].dls_name = %s\n", j,
|
|
sip->dls_serpath[j].dls_name);
|
|
|
|
Engine engine;
|
|
engine.module = mod;
|
|
*(void **)&engine.init = dlsym(mod, "init");
|
|
*(void **)&engine.event = dlsym(mod, "event");
|
|
*(void **)&engine.iterate = dlsym(mod, "iterate");
|
|
*(void **)&engine.quit = dlsym(mod, "quit");
|
|
|
|
assert(engine.init);
|
|
assert(engine.event);
|
|
assert(engine.iterate);
|
|
assert(engine.quit);
|
|
|
|
return engine;
|
|
}
|
|
|
|
int main(int argc, char **argv) {
|
|
|
|
signal(SIGUSR1, reload_signal_handler);
|
|
|
|
EngineData state;
|
|
|
|
Engine hiisi = load_hiisi();
|
|
if (!hiisi.module) {
|
|
printf("%s\n", dlerror());
|
|
return 1;
|
|
}
|
|
|
|
hiisi.init(&state, argc, argv);
|
|
while (hiisi.event(&state)) {
|
|
hiisi.iterate(&state);
|
|
if (reload_requested) {
|
|
dlclose(hiisi.module);
|
|
hiisi = load_hiisi();
|
|
reload_requested = false;
|
|
}
|
|
}
|
|
|
|
dlclose(hiisi.module);
|
|
|
|
return 0;
|
|
}
|