Begin support for watching dgamelaunch games.

watcher.c is a subprocess which uses inotify to watch the inprogress
directories.  A C program is used because node's fs.watch() can't tell
the difference between creation and deletion.
This commit is contained in:
John "Elwin" Edwards 2014-04-01 11:23:25 -07:00
parent e855ba2f58
commit f605244ae6
2 changed files with 136 additions and 0 deletions

101
watcher.c Normal file
View file

@ -0,0 +1,101 @@
#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;
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);
select(ifd + 1, &rfds, NULL, NULL, NULL);
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)) {
read(0, &typecode, 1);
if (typecode == '\n')
done = 1;
}
}
close(ifd);
return 0;
}