hexagram/src/module.c

140 lines
2.4 KiB
C
Raw Normal View History

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>
#include <X11/Xlib.h>
2019-05-19 16:01:19 -05:00
#include <hexagram/module.h>
#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;
}