Esempio n. 1
0
int main(int argc, const char *argv[])
{
  /*
   * a subprocess will initially inherit the process group of its parent. the
   * process group may have a control terminal associated with it, which would
   * be the first tty device opened by the group leader. typically the group
   * leader is your shell and the control terminal is your login device. a
   * subset of signals triggered on the control terminal are sent to all members
   * of the process group, in large part to facilitate sane and consistent
   * cleanup (ex: control terminal was closed).
   *
   * so why the overly descriptive lecture style comment?
   *   1. SIGINT and SIGQUIT are among the signals with this behavior
   *   2. a number of applications gank the above for their own use
   *   3. ruby's insanely useful "guard" is one of these applications
   *   4. despite having some level of understanding of POSIX signals and a few
   *      of the scenarios that might cause problems, i learned this one only
   *      after reading ruby 1.9's process.c
   *   5. if left completely undocumented, even slightly obscure bugfixes
   *      may be removed as cruft by a future maintainer
   *
   * hindsight is 20/20 addition: if you're single-threaded and blocking on IO
   * with a subprocess, then handlers for deferrable signals might not get run
   * when you expect them to. In the case of Ruby 1.8, that means making use of
   * IO::select, which will preserve correct signal handling behavior.
   */
  if (setpgid(0,0) < 0) {
    fprintf(stderr, "Unable to set new process group.\n");
    return 1;
  }

  parse_cli_settings(argc, argv);

  FSEventStreamContext context = {0, NULL, NULL, NULL, NULL};
  FSEventStreamRef stream;
  stream = FSEventStreamCreate(kCFAllocatorDefault,
                               (FSEventStreamCallback)&callback,
                               &context,
                               config.paths,
                               config.sinceWhen,
                               config.latency,
                               config.flags);

#ifdef DEBUG
  FSEventStreamShow(stream);
  fprintf(stderr, "\n");
  fflush(stderr);
#endif

  FSEventStreamScheduleWithRunLoop(stream,
                                   CFRunLoopGetCurrent(),
                                   kCFRunLoopDefaultMode);
  FSEventStreamStart(stream);
  CFRunLoopRun();
  FSEventStreamFlushSync(stream);
  FSEventStreamStop(stream);

  return 0;
}
Esempio n. 2
0
void FSEventsEventPublisher::flush(bool async) {
  if (stream_ != nullptr && stream_started_) {
    if (async) {
      FSEventStreamFlushAsync(stream_);
    } else {
      FSEventStreamFlushSync(stream_);
    }
  }
}
Esempio n. 3
0
void start_watches()
{
    CFStringRef watch_paths[100];
    int         path_count = 0;
    int         i;

    for (i = 0; i < 100; i += 1) {
        if (NULL != FSEVENTS_GLOBAL(watches)[i].path) {
            watch_paths[i] = CFStringCreateWithCString(NULL, FSEVENTS_GLOBAL(watches)[i].path, kCFStringEncodingUTF8);
            path_count++;
        }
    }

    void *callback_info = NULL; // could put stream-specific data here.

    CFArrayRef       watch_path_array = CFArrayCreate(NULL, (void *) watch_paths, path_count, NULL);
    CFAbsoluteTime   latency          = .75; /* Latency in seconds */
    CFRunLoopRef     run_loop         = CFRunLoopGetMain();
    FSEventStreamRef stream;

    /* Create the stream, passing in a callback */
    stream = FSEventStreamCreate(
        NULL,
        (FSEventStreamCallback)&handle_events,
        callback_info,
        watch_path_array,
        kFSEventStreamEventIdSinceNow,
        latency,
        kFSEventStreamCreateFlagNone
    );

    FSEventStreamScheduleWithRunLoop(
        stream,
        run_loop,
        kCFRunLoopDefaultMode
    );

    FSEventStreamStart(stream);
    CFRunLoopRun();
    FSEventStreamFlushSync(stream);
    FSEventStreamStop(stream);
}
Esempio n. 4
0
void FileSystem::triggerFilesystemEventsInternalApple() {
    for(auto d: _directories) {
        FSEventStreamFlushSync(d.second->_eventStream);
    }
}