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
|
#define _POSIX_C_SOURCE 199309L
|
||||||
|
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <poll.h>
|
||||||
|
#include <stdbool.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/inotify.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#define LIBFN "libmod.so"
|
||||||
|
|
||||||
typedef const char *(*getmsg_t)(void);
|
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)
|
int main(void)
|
||||||
{
|
{
|
||||||
const char *libfn = "libmod.so";
|
loadmod();
|
||||||
const char *symn = "getmsg";
|
|
||||||
void *mod = NULL;
|
int fd = inotify_init();
|
||||||
getmsg_t getmsg = NULL;
|
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 };
|
const struct timespec pause = { .tv_nsec = 100000000 };
|
||||||
while (1) {
|
while (1) {
|
||||||
if (mod)
|
int polln = poll(&pfd, 1, 10);
|
||||||
dlclose(mod);
|
if (-1 == polln) {
|
||||||
mod = dlopen(libfn, RTLD_NOW);
|
|
||||||
if (!mod) {
|
|
||||||
fprintf(
|
fprintf(
|
||||||
stderr, "Error: couldn't open %s: %s\n", libfn, dlerror());
|
stderr, "ERROR(%s:%d) %s\n", __FILE__, __LINE__,
|
||||||
return 1;
|
strerror(errno));
|
||||||
}
|
exit(1);
|
||||||
getmsg = (getmsg_t)dlsym(mod, symn);
|
} else if (polln > 0 && pfd.revents & POLLIN) {
|
||||||
if (!getmsg) {
|
static char buf[4096]
|
||||||
fprintf(
|
__attribute__((aligned(__alignof__(struct inotify_event))));
|
||||||
stderr, "Error: couldn't find symbol %s: %s\n", symn,
|
const struct inotify_event *evt;
|
||||||
dlerror());
|
ssize_t i = 0, len = read(fd, buf, sizeof(buf));
|
||||||
return 1;
|
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());
|
printf("\33[2K\r%s", getmsg());
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
nanosleep(&pause, NULL);
|
nanosleep(&pause, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user