]> git.lizzy.rs Git - dungeon_game.git/blob - dungeon.c
Replace dlmopen by dlopen
[dungeon_game.git] / dungeon.c
1 #include <stdio.h>
2 #include <dlfcn.h>
3 #include <stdlib.h>
4 #include <assert.h>
5 #include <dirent.h>
6 #include <string.h>
7
8 struct plugin_list
9 {
10         char *name;
11         void *handle;
12         struct plugin_list *next;
13 };
14
15 struct plugin_list *plugins = NULL;
16 struct plugin_list **next = &plugins;
17
18 static void *load_plugin(const char *name)
19 {
20         for (struct plugin_list *ptr = plugins; ptr != NULL; ptr = ptr->next) {
21                 if (strcmp(ptr->name, name) == 0)
22                         return ptr->handle;
23         }
24
25         size_t len = strlen(name);
26
27         char dependency_file_name[1 + 1 + 7 + 1 + len + 1 + 12 + 1 + 3 + 1];
28         sprintf(dependency_file_name, "./plugins/%s/dependencies.txt", name);
29
30         FILE *dependency_file = fopen(dependency_file_name, "r");
31
32         if (dependency_file) {
33                 char dependency[BUFSIZ];
34
35                 while (fscanf(dependency_file, "%s", dependency) != EOF)
36                         load_plugin(dependency);
37
38                 fclose(dependency_file);
39         }
40
41         char library_name[1 + 1 + 7 + 1 + len + 1 + len + 1 + 2 + 1];
42         sprintf(library_name, "./plugins/%s/%s.so", name, name);
43
44         void *handle = dlopen(library_name, RTLD_NOW | RTLD_GLOBAL);
45
46         if (! handle) {
47                 printf("%s\n", dlerror());
48                 exit(EXIT_FAILURE);
49         }
50
51         char *namebuf = malloc(len + 1);
52         strcpy(namebuf, name);
53
54         *next = malloc(sizeof(struct plugin_list));
55         **next = (struct plugin_list) {
56                 .name = namebuf,
57                 .handle = handle,
58                 .next = NULL,
59         };
60         next = &(*next)->next;
61
62         printf("Loaded %s\n", name);
63
64         return handle;
65 }
66
67 int main()
68 {
69         void *main_plugin = load_plugin("game");
70
71         DIR *dir = opendir("plugins");
72         assert(dir);
73
74         struct dirent *dp;
75
76         while (dp = readdir(dir))
77                 if (dp->d_name[0] != '.')
78                         load_plugin(dp->d_name);
79
80         closedir(dir);
81
82         void (*game_func)() = dlsym(main_plugin, "game");
83         assert(game_func);
84
85         game_func();
86 }
87