93 lines
1.9 KiB
C

/*
* Copyright (c) Camden Dixie O'Brien
* SPDX-License-Identifier: AGPL-3.0-only
*/
#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)
{
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) {
int polln = poll(&pfd, 1, 10);
if (-1 == polln) {
fprintf(
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;
}