2019-05-19 16:01:19 -05:00
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
2019-05-21 09:27:17 -05:00
|
|
|
#include <unistd.h>
|
2019-05-19 16:01:19 -05:00
|
|
|
#include <signal.h>
|
2019-05-21 09:27:17 -05:00
|
|
|
#include <dlfcn.h>
|
2019-05-19 16:01:19 -05:00
|
|
|
#include <sys/wait.h>
|
|
|
|
|
2019-05-25 21:30:31 -05:00
|
|
|
#include <X11/Xlib.h>
|
|
|
|
|
2019-05-19 16:01:19 -05:00
|
|
|
#include <hexagram/module.h>
|
2019-05-25 21:30:31 -05:00
|
|
|
#include <hexagram/window.h>
|
2019-05-19 16:01:19 -05:00
|
|
|
|
|
|
|
struct _hexagram_module {
|
|
|
|
const char *soname;
|
|
|
|
void *handle;
|
|
|
|
char *(*name)();
|
2019-05-21 09:27:17 -05:00
|
|
|
int (*run)(hexagram_dict *buses);
|
|
|
|
pid_t pid;
|
2019-05-19 16:01:19 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
hexagram_module *hexagram_module_open(const char *soname) {
|
|
|
|
hexagram_module *module;
|
|
|
|
|
|
|
|
if ((module = malloc(sizeof(*module))) == NULL) {
|
|
|
|
goto error_malloc;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((module->handle = dlopen(soname, RTLD_LAZY)) == NULL) {
|
|
|
|
goto error_dlopen;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((module->run = dlsym(module->handle, "_hexagram_module_run")) == NULL) {
|
|
|
|
goto error_dlsym;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((module->name = dlsym(module->handle, "_hexagram_module_name")) == NULL) {
|
|
|
|
goto error_dlsym;
|
|
|
|
}
|
|
|
|
|
|
|
|
module->soname = soname;
|
|
|
|
module->pid = 0;
|
|
|
|
|
|
|
|
return module;
|
|
|
|
|
|
|
|
error_dlsym:
|
|
|
|
dlclose(module->handle);
|
|
|
|
|
|
|
|
error_dlopen:
|
|
|
|
free(module);
|
|
|
|
|
|
|
|
error_malloc:
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
const char *hexagram_module_name(hexagram_module *module) {
|
2019-05-21 09:27:17 -05:00
|
|
|
if (module->name == NULL) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2019-05-19 16:01:19 -05:00
|
|
|
return module->name();
|
|
|
|
}
|
|
|
|
|
2019-05-21 09:27:17 -05:00
|
|
|
int hexagram_module_run(hexagram_module *module,
|
|
|
|
hexagram_dict *buses) {
|
|
|
|
if (module->run == NULL) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2019-05-19 16:01:19 -05:00
|
|
|
/*
|
|
|
|
* Module already stopped
|
|
|
|
*/
|
|
|
|
if (module->pid < 0) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2019-05-21 09:27:17 -05:00
|
|
|
if ((module->pid = fork()) < 0) {
|
|
|
|
goto error_fork;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (module->pid == 0) {
|
|
|
|
exit(module->run(buses));
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
error_fork:
|
|
|
|
return -1;
|
2019-05-19 16:01:19 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
int hexagram_module_stop(hexagram_module *module) {
|
|
|
|
if (module->pid <= 0) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (kill(module->pid, SIGTERM) < 0) {
|
|
|
|
if (kill(module->pid, SIGKILL) < 0) {
|
|
|
|
goto error_kill;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (waitpid(module->pid, NULL, 0) < 0) {
|
|
|
|
goto error_waitpid;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Mark the module as stopped
|
|
|
|
*/
|
|
|
|
module->pid = -1;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
error_waitpid:
|
|
|
|
error_kill:
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
int hexagram_module_close(hexagram_module *module) {
|
|
|
|
if (hexagram_module_stop(module) < 0) {
|
|
|
|
goto error_stop_module;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (dlclose(module->handle) < 0) {
|
|
|
|
goto error_dlclose;
|
|
|
|
}
|
|
|
|
|
|
|
|
memset(module, '\0', sizeof(*module));
|
|
|
|
|
2019-05-21 09:27:17 -05:00
|
|
|
free(module);
|
|
|
|
|
2019-05-19 16:01:19 -05:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
error_dlclose:
|
|
|
|
memset(module, '\0', sizeof(*module));
|
|
|
|
|
2019-05-21 09:27:17 -05:00
|
|
|
free(module);
|
|
|
|
|
2019-05-19 16:01:19 -05:00
|
|
|
error_stop_module:
|
|
|
|
return -1;
|
|
|
|
}
|