first commit 🎉
This commit is contained in:
commit
b6a4bb5a58
8 changed files with 213 additions and 0 deletions
105
src/main.c
Normal file
105
src/main.c
Normal file
|
@ -0,0 +1,105 @@
|
|||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <dlfcn.h>
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
#include <err.h>
|
||||
|
||||
#define LIBRARY_PATH_FMT "plugins/%s/%s.so"
|
||||
|
||||
typedef struct {
|
||||
char name[256];
|
||||
void *handle;
|
||||
|
||||
int (*func_load)(void);
|
||||
int (*func_unload)(void);
|
||||
} Plugin;
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
// find plugins
|
||||
DIR *plugins_dir = opendir("plugins");
|
||||
if (plugins_dir == NULL) {
|
||||
errx(EXIT_FAILURE, "failed to read plugins directory");
|
||||
}
|
||||
|
||||
struct dirent *plugin_ent;
|
||||
|
||||
size_t n_plugins = 0;
|
||||
while ((plugin_ent = readdir(plugins_dir)) != NULL) {
|
||||
if (!strcmp(".", plugin_ent->d_name))
|
||||
continue;
|
||||
if (!strcmp("..", plugin_ent->d_name))
|
||||
continue;
|
||||
n_plugins++;
|
||||
}
|
||||
|
||||
rewinddir(plugins_dir);
|
||||
Plugin plugins[n_plugins];
|
||||
size_t n_plugins_ok = 0;
|
||||
|
||||
while ((plugin_ent = readdir(plugins_dir)) != NULL) {
|
||||
if (!strcmp(".", plugin_ent->d_name))
|
||||
continue;
|
||||
if (!strcmp("..", plugin_ent->d_name))
|
||||
continue;
|
||||
|
||||
char *error;
|
||||
|
||||
strcpy(plugins[n_plugins_ok].name, plugin_ent->d_name);
|
||||
char *library_path = NULL;
|
||||
int len = snprintf(library_path, 0, LIBRARY_PATH_FMT, plugins[n_plugins_ok].name, plugins[n_plugins_ok].name);
|
||||
|
||||
library_path = malloc(len);
|
||||
sprintf(library_path, LIBRARY_PATH_FMT, plugins[n_plugins_ok].name, plugins[n_plugins_ok].name);
|
||||
|
||||
plugins[n_plugins_ok].handle = dlopen(library_path, RTLD_LAZY);
|
||||
if (!plugins[n_plugins_ok].handle) {
|
||||
errx(EXIT_FAILURE, "failed to load plugin: %s\n", dlerror());
|
||||
}
|
||||
|
||||
dlerror(); // clear errors
|
||||
|
||||
plugins[n_plugins_ok].func_load = dlsym(plugins[n_plugins_ok].handle, "ari_plugin_load");
|
||||
plugins[n_plugins_ok].func_unload = dlsym(plugins[n_plugins_ok].handle, "ari_plugin_unload");
|
||||
|
||||
error = dlerror();
|
||||
if (error != NULL) {
|
||||
fprintf(stderr, "failed to initialise plugin \"%s\": %s\n", plugins[n_plugins_ok].name, error);
|
||||
dlclose(plugins[n_plugins_ok].handle);
|
||||
continue;
|
||||
}
|
||||
|
||||
int code = plugins[n_plugins_ok].func_load();
|
||||
if (code != EXIT_SUCCESS) {
|
||||
fprintf(stderr, "warn: plugin \"%s\" returned code %d when loaded\n", plugins[n_plugins_ok].name, code);
|
||||
}
|
||||
|
||||
free(library_path);
|
||||
|
||||
n_plugins_ok++;
|
||||
}
|
||||
|
||||
printf("%ld plugins loaded.\n", n_plugins_ok);
|
||||
printf("press any key to continue...");
|
||||
getc(stdin);
|
||||
|
||||
for (int i = 0; i < n_plugins; i++) {
|
||||
if (plugins[n_plugins_ok].handle == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int code = plugins[i].func_unload();
|
||||
if (code != EXIT_SUCCESS) {
|
||||
fprintf(stderr, "warn: plugin \"%s\" returned code %d when unloaded\n", plugins[i].name, code);
|
||||
}
|
||||
|
||||
dlclose(plugins[i].handle);
|
||||
}
|
||||
|
||||
closedir(plugins_dir);
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue