view dglwatcher.c @ 168:0ceaca924b4c

Remove the TermSession 'open' event. Failure is now signaled with a TermSession.failed flag. Playing two games at the same time no longer causes crashes, but it does send the same output to both players.
author John "Elwin" Edwards
date Fri, 09 Jan 2015 08:55:38 -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;
}