Reload module on file changes (using inotify)
This commit is contained in:
parent
519443ed07
commit
dd0ab96b16
84
main.c
84
main.c
@ -6,37 +6,87 @@
|
||||
#define _POSIX_C_SOURCE 199309L
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include <errno.h>
|
||||
#include <poll.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/inotify.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define LIBFN "libmod.so"
|
||||
|
||||
typedef const char *(*getmsg_t)(void);
|
||||
|
||||
static void *mod = NULL;
|
||||
static getmsg_t getmsg = NULL;
|
||||
|
||||
static void loadmod(void)
|
||||
{
|
||||
if (mod)
|
||||
dlclose(mod);
|
||||
mod = dlopen(LIBFN, RTLD_NOW);
|
||||
if (!mod) {
|
||||
fprintf(stderr, "ERROR(%s:%d) %s\n", __FILE__, __LINE__, dlerror());
|
||||
exit(1);
|
||||
}
|
||||
getmsg = (getmsg_t)dlsym(mod, "getmsg");
|
||||
if (!getmsg) {
|
||||
fprintf(stderr, "ERROR(%s:%d) %s\n", __FILE__, __LINE__, dlerror());
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
const char *libfn = "libmod.so";
|
||||
const char *symn = "getmsg";
|
||||
void *mod = NULL;
|
||||
getmsg_t getmsg = NULL;
|
||||
loadmod();
|
||||
|
||||
int fd = inotify_init();
|
||||
if (fd < 0) {
|
||||
fprintf(
|
||||
stderr, "ERROR(%s:%d) %s\n", __FILE__, __LINE__,
|
||||
strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
int wd = inotify_add_watch(fd, "build", IN_MODIFY);
|
||||
if (wd < 0) {
|
||||
fprintf(
|
||||
stderr, "ERROR(%s:%d) %s\n", __FILE__, __LINE__,
|
||||
strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
struct pollfd pfd = { .fd = fd, .events = POLLIN };
|
||||
|
||||
const struct timespec pause = { .tv_nsec = 100000000 };
|
||||
while (1) {
|
||||
if (mod)
|
||||
dlclose(mod);
|
||||
mod = dlopen(libfn, RTLD_NOW);
|
||||
if (!mod) {
|
||||
int polln = poll(&pfd, 1, 10);
|
||||
if (-1 == polln) {
|
||||
fprintf(
|
||||
stderr, "Error: couldn't open %s: %s\n", libfn, dlerror());
|
||||
return 1;
|
||||
}
|
||||
getmsg = (getmsg_t)dlsym(mod, symn);
|
||||
if (!getmsg) {
|
||||
fprintf(
|
||||
stderr, "Error: couldn't find symbol %s: %s\n", symn,
|
||||
dlerror());
|
||||
return 1;
|
||||
stderr, "ERROR(%s:%d) %s\n", __FILE__, __LINE__,
|
||||
strerror(errno));
|
||||
exit(1);
|
||||
} else if (polln > 0 && pfd.revents & POLLIN) {
|
||||
static char buf[4096]
|
||||
__attribute__((aligned(__alignof__(struct inotify_event))));
|
||||
const struct inotify_event *evt;
|
||||
ssize_t i = 0, len = read(fd, buf, sizeof(buf));
|
||||
bool reload = false;
|
||||
while (i < len) {
|
||||
evt = (struct inotify_event *)&buf[i];
|
||||
if (strcmp(LIBFN, evt->name) == 0)
|
||||
reload = true;
|
||||
i += sizeof(struct inotify_event) + evt->len;
|
||||
}
|
||||
if (reload)
|
||||
loadmod();
|
||||
}
|
||||
|
||||
printf("\33[2K\r%s", getmsg());
|
||||
fflush(stdout);
|
||||
nanosleep(&pause, NULL);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user