Reload module on file changes (using inotify)

This commit is contained in:
Camden Dixie O'Brien 2024-12-29 17:07:08 +00:00
parent 519443ed07
commit dd0ab96b16

84
main.c
View File

@ -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;
}