-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathplugins.c
91 lines (72 loc) · 1.63 KB
/
plugins.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#include <config.h>
#include "plugins_t.h"
#include <stdio.h>
#include <stdlib.h>
#ifndef _WIN32
#include <dlfcn.h>
#include <glob.h>
#endif
#include "adt/xmalloc.h"
plugin_t *plugins = NULL;
static void load_plugin(const char *filename)
{
#ifdef _WIN32
// TODO...
#else
//printf("Opening plugin '%s'...\n", filename);
void *handle = dlopen(filename, RTLD_NOW | RTLD_GLOBAL);
if (handle == NULL) {
fprintf(stderr, "Couldn't load plugin '%s': %s\n", filename, dlerror());
return;
}
void *init_func = dlsym(handle, "init_plugin");
if (init_func == NULL) {
dlclose(handle);
fprintf(stderr, "Plugin '%s' has no init_plugin function.\n", filename);
return;
}
plugin_t *plugin = xmalloc(sizeof(plugin[0]));
plugin->init_function = (init_plugin_function) init_func;
plugin->dlhandle = handle;
plugin->next = plugins;
plugins = plugin;
#endif
}
void search_plugins(void)
{
#ifndef _WIN32
/* search for plugins */
glob_t globbuf;
if (glob("plugins/plugin_*.dylib", 0, NULL, &globbuf) == 0) {
for (size_t i = 0; i < globbuf.gl_pathc; ++i) {
const char *filename = globbuf.gl_pathv[i];
load_plugin(filename);
}
globfree(&globbuf);
}
#endif
}
void initialize_plugins(void)
{
/* execute plugin initializers */
plugin_t *plugin = plugins;
while (plugin != NULL) {
plugin->init_function();
plugin = plugin->next;
}
}
void free_plugins(void)
{
#ifndef _WIN32
/* close dl handles */
plugin_t *plugin = plugins;
while (plugin != NULL) {
void *handle = plugin->dlhandle;
if (handle != NULL) {
dlclose(handle);
plugin->dlhandle = NULL;
}
plugin = plugin->next;
}
#endif
}