Mercurial > hg > rlgwebd
view dglwatcher.c @ 192:addc4e3456c4
Begin adding systemd compatibility.
The Makefile can be used to build and install rlgwebd. On systems with
systemd, the unit file controls starting and stopping the service, and
the shell script is not needed.
The unit file uses KillMode=none because socat does not actually stop
rlgwebd, it only asks it to stop and exits without waiting for a
response. Until a better stopping method is introduced, this setting
prevents systemd from killing all the rlgwebd processes as soon as
socat exits.
author | John "Elwin" Edwards |
---|---|
date | Fri, 01 Jan 2016 16:11:34 -0500 |
parents | fba1b34e7554 |
children |
line wrap: on
line source
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/inotify.h> #include <sys/select.h> #include <unistd.h> #include <limits.h> #include <dirent.h> struct watchdir { int wd; char *name; }; char ibuf[sizeof(struct inotify_event) + NAME_MAX + 1]; int startwatch(int ifd, char *dir, struct watchdir *w) { DIR *dstream; struct dirent *ent; w->name = dir; w->wd = inotify_add_watch(ifd, dir, IN_CREATE|IN_DELETE|IN_DELETE_SELF); if (w->wd < 0) { fprintf(stderr, "Could not watch %s\n", dir); return 1; } dstream = opendir(dir); if (dstream == NULL) { fprintf(stderr, "%s is not a readable directory\n", dir); inotify_rm_watch(ifd, w->wd); w->wd = -1; return 1; } ent = readdir(dstream); while (ent != NULL) { if (strcmp(ent->d_name, ".") && strcmp(ent->d_name, "..")) printf("E %s/%s\n", dir, ent->d_name); ent = readdir(dstream); } closedir(dstream); fflush(stdout); return 0; } int main(int argc, char *argv[]) { int ifd, rsize, off, done, nwatchers, i, result; char typecode; struct inotify_event *iev; fd_set rfds; struct watchdir *watchers; done = 0; nwatchers = argc - 1; iev = (struct inotify_event *) ibuf; ifd = inotify_init(); if (nwatchers == 0) { watchers = malloc(sizeof(struct watchdir)); nwatchers = 1; startwatch(ifd, ".", watchers); } else { watchers = malloc(nwatchers * sizeof(struct watchdir)); for (i = 0; i < nwatchers; i++) { startwatch(ifd, argv[i+1], watchers + i); } } while (!done) { FD_ZERO(&rfds); FD_SET(0, &rfds); FD_SET(ifd, &rfds); result = select(ifd + 1, &rfds, NULL, NULL, NULL); if (result < 0) { /* Something went wrong. */ break; } if (FD_ISSET(ifd, &rfds)) { off = 0; rsize = read(ifd, ibuf, sizeof(struct inotify_event) + NAME_MAX + 1); while (off < rsize) { iev = (struct inotify_event *) (ibuf + off); if (iev->mask & IN_CREATE) typecode = 'C'; else if (iev->mask & IN_DELETE) typecode = 'D'; else typecode = '?'; for (i = 0; i < nwatchers; i++) { if (watchers[i].wd == iev->wd) printf("%c %s/%s\n", typecode, watchers[i].name, iev->name); } off += sizeof(struct inotify_event) + iev->len; } fflush(stdout); } if (FD_ISSET(0, &rfds)) { result = read(0, &typecode, 1); if (result <= 0) { /* EOF on stdin: controlling process probably died. */ done = 1; } if (typecode == '\n') done = 1; } } close(ifd); return 0; }