/* * Copyright (c) Camden Dixie O'Brien * SPDX-License-Identifier: AGPL-3.0-only */ #define _POSIX_C_SOURCE 199309L #include #include #include #include #include #include #include #include #include #include #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; }