aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile7
-rw-r--r--dungeon.c46
2 files changed, 53 insertions, 0 deletions
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..5241f4f
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,7 @@
+all: dungeon plugins
+
+dungeon: dungeon.c
+ cc -g -o dungeon dungeon.c -ldl -D_GNU_SOURCE
+
+plugins:
+ make -f plugins/*/Makefile
diff --git a/dungeon.c b/dungeon.c
new file mode 100644
index 0000000..a1b0064
--- /dev/null
+++ b/dungeon.c
@@ -0,0 +1,46 @@
+#include <stdio.h>
+#include <dlfcn.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <dirent.h>
+#include <string.h>
+
+static void *load_plugin(const char *name)
+{
+ size_t len = strlen(name);
+ char filename[1 + 1 + 7 + 1 + len + 1 + len + 1 + 2 + 1];
+ sprintf(filename, "./plugins/%s/%s.so", name, name);
+
+ void *plugin_handle = dlmopen(LM_ID_BASE, filename, RTLD_NOW | RTLD_GLOBAL);
+
+ if (! plugin_handle) {
+ printf("%s\n", dlerror());
+ exit(EXIT_FAILURE);
+ }
+
+ return plugin_handle;
+}
+
+int main()
+{
+ void *main_plugin = load_plugin("game");
+
+ DIR *dir = opendir("plugins");
+ assert(dir);
+
+ struct dirent *dp;
+
+ while (dp = readdir(dir)) {
+ if (dp->d_name[0] != '.' && strcmp(dp->d_name, "game") != 0) {
+ load_plugin(dp->d_name);
+ }
+ }
+
+ closedir(dir);
+
+ void (*game_func)() = dlsym(main_plugin, "game");
+ assert(game_func);
+
+ game_func();
+}
+