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:
parent
e855ba2f58
commit
f605244ae6
2 changed files with 136 additions and 0 deletions
35
rlgwebd.js
35
rlgwebd.js
|
|
@ -944,6 +944,38 @@ function findClient(formdata, playersOnly) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function startProgressWatcher() {
|
||||||
|
var watchdirs = [];
|
||||||
|
for (var gname in games) {
|
||||||
|
watchdirs.push(path.join("/dgldir/inprogress", gname));
|
||||||
|
}
|
||||||
|
var subproc = child_process.spawn("/bin/watcher", watchdirs);
|
||||||
|
subproc.stdout.setEncoding('utf8');
|
||||||
|
subproc.stdout.on('data', function (chunk) {
|
||||||
|
var fname = chunk.slice(2, -1);
|
||||||
|
var filere = /.*\/([^\/]*)\/([^\/:]*):(node:)?(.*)/;
|
||||||
|
var matchresult = fname.match(filere);
|
||||||
|
if (!matchresult || matchresult[3])
|
||||||
|
return;
|
||||||
|
gname = matchresult[1];
|
||||||
|
pname = matchresult[2];
|
||||||
|
if (chunk[0] == "E") {
|
||||||
|
tslog("DGL: %s is playing %s: %s", pname, gname, fname)
|
||||||
|
}
|
||||||
|
else if (chunk[0] == "C") {
|
||||||
|
tslog("DGL: %s started playing %s: %s", pname, gname, fname)
|
||||||
|
}
|
||||||
|
else if (chunk[0] == "D") {
|
||||||
|
tslog("DGL: %s finished playing %s: %s", pname, gname, fname)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
tslog("Watcher says: %s", chunk)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
subproc.stdout.resume();
|
||||||
|
return subproc;
|
||||||
|
}
|
||||||
|
|
||||||
function serveStatic(req, res, fname) {
|
function serveStatic(req, res, fname) {
|
||||||
var nname = path.normalize(fname);
|
var nname = path.normalize(fname);
|
||||||
if (nname == "" || nname == "/")
|
if (nname == "" || nname == "/")
|
||||||
|
|
@ -1374,6 +1406,7 @@ function conHandler(chunk) {
|
||||||
for (var sessid in sessions) {
|
for (var sessid in sessions) {
|
||||||
sessions[sessid].close();
|
sessions[sessid].close();
|
||||||
}
|
}
|
||||||
|
progressWatcher.stdin.end("\n");
|
||||||
setTimeout(shutdown, 2000);
|
setTimeout(shutdown, 2000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1396,6 +1429,7 @@ if (process.getuid() != 0) {
|
||||||
|
|
||||||
var httpServer; // declare here so shutdown() can find it
|
var httpServer; // declare here so shutdown() can find it
|
||||||
var wsServer;
|
var wsServer;
|
||||||
|
var progressWatcher;
|
||||||
|
|
||||||
/* This could be nonblocking, but nothing else can start yet anyway. */
|
/* This could be nonblocking, but nothing else can start yet anyway. */
|
||||||
if (fs.existsSync(ctlsocket)) {
|
if (fs.existsSync(ctlsocket)) {
|
||||||
|
|
@ -1433,6 +1467,7 @@ ctlServer.listen(ctlsocket, function () {
|
||||||
wsServer = new WebSocketServer({"httpServer": httpServer});
|
wsServer = new WebSocketServer({"httpServer": httpServer});
|
||||||
wsServer.on("request", wsHandler);
|
wsServer.on("request", wsHandler);
|
||||||
tslog('WebSockets are online');
|
tslog('WebSockets are online');
|
||||||
|
progressWatcher = startProgressWatcher();
|
||||||
setInterval(pushStatus, 4000);
|
setInterval(pushStatus, 4000);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
101
watcher.c
Normal file
101
watcher.c
Normal 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;
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue