Mercurial > hg > rlgwebd
view dglwatcher.c @ 174:dc12ba30d559
Fix further crashes when following dgamelaunch games.
The crashes apparently resulted from reading a ttyrec header and
then trying to read the data chunk before dgamelaunch produced it.
When the data chunk did become available, it would be read by the
header function.
The simplest solution was to store the position for reading the
ttyrec file in the DGLSession, and to leave it unchanged if anything
unexpected occurs when reading.
author | John "Elwin" Edwards |
---|---|
date | Mon, 12 Jan 2015 17:10:35 +0000 |
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; }