예제 #1
0
/**
 * Create a new watch for a given path
 */
static void add_watch(char *wpath, struct thread_env *env) {
  // Copied latency from Watchman
  // https://github.com/facebook/watchman/blob/5161cb6eeca4405bcaea820f377cd6d2f51ce1f4/root.c#L1838
  CFAbsoluteTime latency = 0.0001;
  FSEventStreamRef stream;
  CFStringRef path = CFStringCreateWithCString(NULL, wpath, kCFStringEncodingMacRoman);
  CFArrayRef pathsToWatch = CFArrayCreate(NULL, (const void**)&path, 1, NULL);

  // Docs say FSEventStreamCreate copies the fields out of this context, so it
  // doesn't need to be long lived
  FSEventStreamContext context = {};
  memset(&context, 0, sizeof(FSEventStreamContext));
  context.info = env;
  stream = FSEventStreamCreate(
    NULL,
    &watch_callback,
    &context,
    pathsToWatch,
    kFSEventStreamEventIdSinceNow,
    latency,
    kFSEventStreamCreateFlagFileEvents
  );
  FSEventStreamScheduleWithRunLoop(
    stream,
    CFRunLoopGetCurrent(),
    kCFRunLoopDefaultMode
  );
  FSEventStreamStart(stream);
}
예제 #2
0
int main (int argc, const char * argv[]) {
	// Show help
	if (argc != 2 || strncmp(argv[1], "-h", 2) == 0) {
		printf("Sleep until a file in or below the watchdir is modified.\n");
		printf("Usage: fsevent_watch /path/to/watchdir\n");
		exit(1);
	}

	// Create event stream
  CFStringRef pathToWatch = CFStringCreateWithCString(kCFAllocatorDefault, argv[1], kCFStringEncodingUTF8);
  CFArrayRef pathsToWatch = CFArrayCreate(NULL, (const void **)&pathToWatch, 1, NULL);
  void *callbackInfo = NULL;
  FSEventStreamRef stream;
  CFAbsoluteTime latency = 0.5;
  stream = FSEventStreamCreate(
               kCFAllocatorDefault,
               callback,
               callbackInfo,
               pathsToWatch,
               kFSEventStreamEventIdSinceNow,
               latency,
               kFSEventStreamCreateFlagNone
  );

	// Add stream to run loop
  FSEventStreamScheduleWithRunLoop(stream, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
	FSEventStreamStart(stream);
	CFRunLoopRun();

	// Exit
	return 2;
}
예제 #3
0
//set up fsevents and callback
int main(int argc, char **argv) {

  if(argc != 2) {
    fprintf(stderr, "You must specify a directory to watch for changes.\n");
    exit(1);
  }

  CFStringRef mypath = CFStringCreateWithCString(NULL, argv[1], kCFStringEncodingUTF8); 
  CFArrayRef pathsToWatch = CFArrayCreate(NULL, (const void **)&mypath, 1, NULL); 
  void *callbackInfo = NULL; 
  FSEventStreamRef stream; 
  CFAbsoluteTime latency = 1.0;

  stream = FSEventStreamCreate(NULL,
    &callback,
    callbackInfo,
    pathsToWatch,
    kFSEventStreamEventIdSinceNow,
    latency,
    kFSEventStreamCreateFlagNone
  ); 

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

}
예제 #4
0
파일: fsevapi.c 프로젝트: FihlaTV/fsmon
static bool fm_begin (FileMonitor *fm) {
        FSEventStreamCreateFlags flags = kFSEventStreamCreateFlagFileEvents;
        FSEventStreamContext ctx = {
                0,
                fm,
                NULL,
                NULL,
                NULL
        };

	if (!fm->root) {
		fm->root = "/";
	}
        CFMutableArrayRef paths = CFArrayCreateMutable (NULL, 1, NULL);
	CFStringRef cfs_path = CFStringCreateWithCString (NULL, fm->root,
		kCFStringEncodingUTF8);
	CFArrayAppendValue (paths, cfs_path);

        FSEventStreamRef stream = FSEventStreamCreate (NULL, &event_cb,
		&ctx, paths, kFSEventStreamEventIdSinceNow, 0, flags);
        FSEventStreamScheduleWithRunLoop (stream, CFRunLoopGetCurrent(),
		kCFRunLoopDefaultMode);
        FSEventStreamStart (stream);
	return true;
}
예제 #5
0
int main(int argc, char* argv[]) {
  if (argc != 2) {
    fprintf(stderr, "usage: %s <directory-to-watch>\n", argv[0]);
    exit(1);
  }

  CFStringRef path = CFStringCreateWithCString(
    kCFAllocatorDefault,
    argv[1],
    kCFStringEncodingUTF8
  );

  CFArrayRef pathsToWatch = CFArrayCreate(
    kCFAllocatorDefault,
    (const void **)&path,
    1,
    NULL
  );

  // create stream
  FSEventStreamRef stream = FSEventStreamCreate(
    kCFAllocatorDefault,
    _eventStreamCallback,
    NULL, // context for callback
    pathsToWatch,
    kFSEventStreamEventIdSinceNow,
    0, // latency
    kFSEventStreamCreateFlagFileEvents // this flag was introduced in 10.7
  );

  FSEventStreamScheduleWithRunLoop(stream, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
  FSEventStreamStart(stream);
  CFRunLoopRun();
  return EXIT_SUCCESS; // CFRunLoopRun never returns, we never get here
}
예제 #6
0
파일: fswatch.c 프로젝트: bclennox/fswatch
//set up fsevents and callback
int main(int argc, char **argv) {

  if(argc != 3) {
    fprintf(stderr, "You must specify a directory to watch and a command to execute on change\n");
    exit(1);
  }

  to_run = argv[2];

  CFStringRef mypath = CFStringCreateWithCString(NULL, argv[1], kCFStringEncodingUTF8); 
  CFArrayRef pathsToWatch = CFStringCreateArrayBySeparatingStrings (NULL, mypath, CFSTR(":"));

  void *callbackInfo = NULL; 
  FSEventStreamRef stream; 
  CFAbsoluteTime latency = 1.0;

  stream = FSEventStreamCreate(NULL,
    &callback,
    callbackInfo,
    pathsToWatch,
    kFSEventStreamEventIdSinceNow,
    latency,
    kFSEventStreamCreateFlagNone
  ); 

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

}
예제 #7
0
int main( int argc, char* argv[] ){

    /* Define variables and create a CFArray object containing CFString objects containing paths to watch. */
    CFStringRef mypath      = CFStringCreateWithCString( NULL, argv[ 1 ], kCFStringEncodingUTF8);
    CFArrayRef pathsToWatch = CFArrayCreate( NULL, ( const void ** ) &mypath, 1, NULL );
    void *callbackInfo      = NULL; // could put stream-specific data here. FSEventStreamRef stream;*/
    CFAbsoluteTime latency  = 3.0; /* Latency in seconds */
    FSEventStreamRef stream;

    /* Create the stream, passing in a callback */
    stream = FSEventStreamCreate(

        NULL,
        &myCallbackFunction,
        callbackInfo,
        pathsToWatch,
        kFSEventStreamEventIdSinceNow, /* Or a previous event ID */
        latency,
        kFSEventStreamCreateFlagFileEvents /* Flags explained in reference: https://developer.apple.com/library/mac/documentation/Darwin/Reference/FSEvents_Ref/Reference/reference.html */

    );

    /* Create the stream before calling this. */
    FSEventStreamScheduleWithRunLoop( stream, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode );
    FSEventStreamStart( stream );
    CFRunLoopRun();

    return 0;

}
예제 #8
0
Autobuild::Autobuild(const AutobuildConfiguration& conf) : mPimpl(new Autobuild::Impl) {
    
    
    CFStringRef path = CFStringCreateWithCString(NULL, conf.directory.c_str(), kCFStringEncodingUTF8 );
    CFArrayRef pathsToWatch = CFArrayCreate(NULL, (const void **)&path, 1, NULL);

    FSEventStreamContext context;
    memset(&context,0,sizeof(context));
    context.version = 0;
    context.info = mPimpl;

    mPimpl->ignore = conf.ignore;
    mPimpl->last = 0;
    mPimpl->command = conf.command.c_str();

    mPimpl->stream = FSEventStreamCreate(NULL,
       &fseventerCallback,
       &context,
       pathsToWatch,
       kFSEventStreamEventIdSinceNow,
       conf.latency,
       kFSEventStreamCreateFlagNone
    );


    FSEventStreamScheduleWithRunLoop(mPimpl->stream, CFRunLoopGetMain(), kCFRunLoopDefaultMode);
    FSEventStreamStart(mPimpl->stream);

    CFRelease(path);
    CFRelease(pathsToWatch);
    
}
예제 #9
0
FSEventStreamRef CreateEventStream( DirWatchMap path )
{
  if ( ( g_Stream == NULL ) && CanRunNotifications() )
  {
    CFStringRef* pathLists = (CFStringRef*)malloc( sizeof(CFStringRef*) * path.size() );
    int   index = 0;
    for ( DirWatchMap::iterator it = path.begin() ; it != path.end(); ++it)
    {
      pathLists[index] = CFStringCreateWithFileSystemRepresentation( NULL, OsString(it->path).c_str());
      index++;
    }
    CFArrayRef pathsToWatch = CFArrayCreate(NULL, (const void **)pathLists, index, NULL);

    FSEventStreamContext *callbackInfo = NULL;
 
    FSEventStreamRef stream = FSEventStreamCreate(NULL, &fsevent_callback, callbackInfo, pathsToWatch,
        kFSEventStreamEventIdSinceNow, 1.0, kFSEventStreamCreateFlagFileEvents );

    CFRelease( pathsToWatch );
    free( pathLists );

    FSEventStreamScheduleWithRunLoop(stream, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
    if (!FSEventStreamStart(stream)) 
      debug_warn(L"event_loop FSEventStreamStart failed!"); 
    else
      return stream;
  }
  return NULL;
}
예제 #10
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;
}
VError XMacFileSystemNotification::StartWatchingForChanges( const VFolder &inFolder, VFileSystemNotifier::EventKind inKindFilter, VFileSystemNotifier::IEventHandler *inHandler, sLONG inLatency )
{
	// We need to get the folder's path into an array for us to pass along to the OS call.
	VString posixPathString;
	inFolder.GetPath( posixPathString, FPS_POSIX);

	VStringConvertBuffer buffer( posixPathString, VTC_UTF_8);
	std::string posixPath( buffer.GetCPointer());

	CFStringRef pathRef = posixPathString.MAC_RetainCFStringCopy();
	CFArrayRef pathArray = CFArrayCreate( NULL, (const void **)&pathRef, 1, NULL );
	
	FSEventStreamContext context = { 0 };
	
	// The latency the user passed us is expressed in milliseconds, but the OS call requires the latency to be
	// expressed in seconds.
	CFTimeInterval latency = (inLatency / 1000.0);
	
	// Now we can make our change data object
	XMacChangeData *data = new XMacChangeData( inFolder.GetPath(), posixPath, inKindFilter, VTask::GetCurrent(), inHandler, this);
	context.info = data;
	data->fStreamRef = FSEventStreamCreate( NULL, &FSEventCallback, &context, pathArray, kFSEventStreamEventIdSinceNow, latency, kFSEventStreamCreateFlagNone );
	if (data->fStreamRef == NULL)
	{
		CFRelease( pathArray );
		CFRelease( pathRef );
		ReleaseRefCountable( &data);
		return MAKE_NATIVE_VERROR( errno );
	}
	
	// We also need to take an initial snapshot of the directory for us to compare again
	CreateDirectorySnapshot( posixPath, data->fSnapshot, true );
	
	// Now we can add the data object we just made to our list
	fOwner->PushChangeData( data);

	// Next, we can schedule this to run on the main event loop
	FSEventStreamScheduleWithRunLoop( data->fStreamRef, CFRunLoopGetMain(), kCFRunLoopDefaultMode );

	CFRelease( pathArray );
	CFRelease( pathRef );

	// Now that we've scheduled the stream to run on a helper thread, all that is left is to
	// start executing the stream
	VError err;
	if (FSEventStreamStart( data->fStreamRef ))
	{
		err = VE_OK;
	}
	else
	{
		err = MAKE_NATIVE_VERROR( errno );
	}
	ReleaseRefCountable( &data);
	
	return err;
}
예제 #12
0
static FSEventStreamRef
add_watch (SeafWTMonitor *monitor, const char* repo_id, const char* worktree)
{
    SeafWTMonitorPriv *priv = monitor->priv;
    RepoWatchInfo *info;
    double latency = 0.25; /* unit: second */

    char *worktree_nfd = g_utf8_normalize (worktree, -1, G_NORMALIZE_NFD);

    CFStringRef mypaths[1];
    mypaths[0] = CFStringCreateWithCString (kCFAllocatorDefault,
                                            worktree_nfd, kCFStringEncodingUTF8);
    g_free (worktree_nfd);
    CFArrayRef pathsToWatch = CFArrayCreate(NULL, (const void **)mypaths, 1, NULL);
    FSEventStreamRef stream;

    /* Create the stream, passing in a callback */
    seaf_debug("Use kFSEventStreamCreateFlagWatchRoot\n");
    // kFSEventStreamCreateFlagFileEvents does not work for libraries with name
    // containing accent characters.
    struct FSEventStreamContext ctx = {0, monitor, NULL, NULL, NULL};
    stream = FSEventStreamCreate(kCFAllocatorDefault,
                                 stream_callback,
                                 &ctx,
                                 pathsToWatch,
                                 kFSEventStreamEventIdSinceNow,
                                 latency,
                                 kFSEventStreamCreateFlagWatchRoot
                                 );

    CFRelease (mypaths[0]);
    CFRelease (pathsToWatch);

    if (!stream) {
        seaf_warning ("[wt] Failed to create event stream.\n");
        return stream;
    }

    FSEventStreamScheduleWithRunLoop(stream, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
    FSEventStreamStart (stream);
    /* FSEventStreamShow (stream); */
    seaf_debug ("[wt mon] Add repo %s watch success: %s.\n", repo_id, worktree);

    pthread_mutex_lock (&priv->hash_lock);
    g_hash_table_insert (priv->handle_hash,
                         g_strdup(repo_id), (gpointer)(long)stream);

    info = create_repo_watch_info (repo_id, worktree);
    g_hash_table_insert (priv->info_hash, (gpointer)(long)stream, info);
    pthread_mutex_unlock (&priv->hash_lock);

    /* An empty path indicates repo-mgr to scan the whole worktree. */
    add_event_to_queue (info->status, WT_EVENT_CREATE_OR_UPDATE, "", NULL);
    return stream;
}
예제 #13
0
  void fsevents_monitor::run()
  {
    if (stream) return;

    // parsing paths
    vector<CFStringRef> dirs;

    for (string path : paths)
    {
      dirs.push_back(CFStringCreateWithCString(NULL,
                                               path.c_str(),
                                               kCFStringEncodingUTF8));
    }

    if (dirs.size() == 0) return;

    CFArrayRef pathsToWatch =
      CFArrayCreate(NULL,
                    reinterpret_cast<const void **> (&dirs[0]),
                    dirs.size(),
                    &kCFTypeArrayCallBacks);

    FSEventStreamContext *context = new FSEventStreamContext();
    context->version = 0;
    context->info = this;
    context->retain = nullptr;
    context->release = nullptr;
    context->copyDescription = nullptr;

    FSW_ELOG(_("Creating FSEvent stream...\n"));
    unique_lock<mutex> run_loop_lock(run_mutex);
    stream = FSEventStreamCreate(NULL,
                                 &fsevents_monitor::fsevents_callback,
                                 context,
                                 pathsToWatch,
                                 kFSEventStreamEventIdSinceNow,
                                 latency,
                                 kFSEventStreamCreateFlagFileEvents);

    if (!stream) throw libfsw_exception(_("Event stream could not be created."));

    run_loop = CFRunLoopGetCurrent();
    run_loop_lock.unlock();

    FSW_ELOG(_("Scheduling stream with run loop...\n"));
    FSEventStreamScheduleWithRunLoop(stream,
                                     run_loop,
                                     kCFRunLoopDefaultMode);

    FSW_ELOG(_("Starting event stream...\n"));
    FSEventStreamStart(stream);

    FSW_ELOG(_("Starting run loop...\n"));
    CFRunLoopRun();
  }
bool FDirectoryWatchRequestMac::Init(const FString& InDirectory)
{
	if ( InDirectory.Len() == 0 )
	{
		// Verify input
		return false;
	}

	if( bRunning )
	{
		Shutdown();
	}

	bEndWatchRequestInvoked = false;

	// Make sure the path is absolute
	const FString FullPath = FPaths::ConvertRelativePathToFull(InDirectory);

	// Set up streaming and turn it on
	CFStringRef FullPathMac = FPlatformString::TCHARToCFString(*FullPath);
	CFArrayRef PathsToWatch = CFArrayCreate(NULL, (const void**)&FullPathMac, 1, NULL);

	CFAbsoluteTime Latency = 0.2;	// seconds

	FSEventStreamContext Context;
	Context.version = 0;
	Context.info = this;
	Context.retain = NULL;
	Context.release = NULL;
	Context.copyDescription = NULL;

	EventStream = FSEventStreamCreate( NULL,
		&DirectoryWatchMacCallback,
		&Context,
		PathsToWatch,
		kFSEventStreamEventIdSinceNow,
		Latency,
		kFSEventStreamCreateFlagUseCFTypes | kFSEventStreamCreateFlagNoDefer | kFSEventStreamCreateFlagFileEvents
	);

	CFRelease(PathsToWatch);
	CFRelease(FullPathMac);

	if( !EventStream )
	{
		return false;
	}

	FSEventStreamScheduleWithRunLoop( EventStream, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode );
	FSEventStreamStart( EventStream );

	bRunning = true;

	return true;
}
예제 #15
0
bool MacFileSystemChangeNotifier::internalAddNotification( const Torque::Path& dir )
{
    // Map the path.

    Torque::Path fullFSPath = mFS->mapTo( dir );
    String osPath = PathToOS( fullFSPath );

    // Create event stream.

    Event* event = new Event;

    CFStringRef path = CFStringCreateWithCharacters( NULL, osPath.utf16(), osPath.numChars() );
    CFArrayRef paths = CFArrayCreate( NULL, ( const void** ) &path, 1, NULL );

    FSEventStreamRef stream;
    CFAbsoluteTime latency = 3.f;

    FSEventStreamContext context;
    dMemset( &context, 0, sizeof( context ) );
    context.info = event;

    stream = FSEventStreamCreate(
                 NULL,
                 &fsNotifyCallback,
                 &context,
                 paths,
                 kFSEventStreamEventIdSinceNow,
                 latency,
                 kFSEventStreamCreateFlagNone
             );

    event->mStream = stream;
    event->mDir = dir;
    event->mHasChanged = false;

    mEvents.push_back( event );

    // Put it in the run loop and start the stream.

    FSEventStreamScheduleWithRunLoop( stream, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode );
    FSEventStreamStart( stream );

    CFRelease( path );
    CFRelease( paths );

#ifdef DEBUG_SPEW
    Platform::outputDebugString( "[MacFileSystemChangeNotifier] Added change notification %i to '%s' (full path: %s)",
                                 mEvents.size(), dir.getFullPath().c_str(), osPath.c_str() );
#endif

    return true;
}
예제 #16
0
void *WatcherMain(void *d) {
    Watcher w = *(Watcher *)d;
    BOOL done = NO;
    CFRunLoopRef runLoop = CFRunLoopGetCurrent();
    FSEventStreamScheduleWithRunLoop(w.stream, runLoop, kCFRunLoopDefaultMode);
    BOOL started = FSEventStreamStart(w.stream);
    do {
        SInt32 result = CFRunLoopRunInMode(kCFRunLoopDefaultMode, 10, YES);
        if ((result == kCFRunLoopRunStopped) || (result == kCFRunLoopRunFinished))
            done = YES;
    } while (!done);
    return NULL;
}
예제 #17
0
static FSEventStreamRef
add_watch (SeafWTMonitor *monitor, const char* repo_id, const char* worktree)
{
    SeafWTMonitorPriv *priv = monitor->priv;
    const char *path = worktree;
    RepoWatchInfo *info;
    double latency = 0.25; /* unit: second */

    CFStringRef mypath = CFStringCreateWithCString (kCFAllocatorDefault,
                                                    path, kCFStringEncodingUTF8);
    CFArrayRef pathsToWatch = CFArrayCreate(NULL, (const void **)&mypath, 1, NULL);
    FSEventStreamRef stream;

    /* Create the stream, passing in a callback */
    struct FSEventStreamContext ctx = {0, monitor, NULL, NULL, NULL};
    stream = FSEventStreamCreate(kCFAllocatorDefault,
                                 stream_callback,
                                 &ctx,
                                 pathsToWatch,
                                 kFSEventStreamEventIdSinceNow,
                                 latency,
                                 kFSEventStreamCreateFlagFileEvents /* deprecated OSX 10.6 support*/
        );

    CFRelease (mypath);
    CFRelease (pathsToWatch);

    if (!stream) {
        seaf_warning ("[wt] Failed to create event stream \n");
        return stream;
    }

    FSEventStreamScheduleWithRunLoop(stream, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
    FSEventStreamStart (stream);
#ifdef FSEVENT_DEBUG
    FSEventStreamShow (stream);
    seaf_debug ("[wt mon] Add repo %s watch success :%s.\n", repo_id, repo->worktree);
#endif

    pthread_mutex_lock (&priv->hash_lock);
    g_hash_table_insert (priv->handle_hash,
                         g_strdup(repo_id), (gpointer)(long)stream);

    info = create_repo_watch_info (repo_id, worktree);
    g_hash_table_insert (priv->info_hash, (gpointer)(long)stream, info);
    pthread_mutex_unlock (&priv->hash_lock);

    /* An empty path indicates repo-mgr to scan the whole worktree. */
    add_event_to_queue (info->status, WT_EVENT_CREATE_OR_UPDATE, "", NULL);
    return stream;
}
예제 #18
0
파일: fswatch.c 프로젝트: pieper/fswatch
//set up fsevents and callback
int main(int argc, char **argv) {

  if(argc < 3) {
    fprintf(stderr, "usage: %s directory command [argument ...]\n", argv[0]);
    exit(1);
  }

  int n_args = argc - 2;

  // find total length of argument to bash -c, including spaces
  int n_bash_arg_chars = 0;
  for(int i=2; i<argc; ++i) {
    n_bash_arg_chars += strlen(argv[i]) + 1;
  }

  // build the space-separated string argument
  char bash_arg[n_bash_arg_chars];
  int i_chars = 0;
  for(int i=2; i<argc; ++i) {
    memcpy(&bash_arg[i_chars], argv[i], strlen(argv[i]) * sizeof(char));
    i_chars += strlen(argv[i]);
    bash_arg[i_chars++] = ' ';
  }
  bash_arg[i_chars - 1] = 0;

  // update the global bash command to be run
  bash_command[2] = bash_arg;

  CFStringRef mypath = CFStringCreateWithCString(NULL, argv[1], kCFStringEncodingUTF8); 
  CFArrayRef pathsToWatch = CFStringCreateArrayBySeparatingStrings (NULL, mypath, CFSTR(":"));

  void *callbackInfo = NULL; 
  FSEventStreamRef stream; 
  CFAbsoluteTime latency = 0;

  stream = FSEventStreamCreate(NULL,
    &callback,
    callbackInfo,
    pathsToWatch,
    kFSEventStreamEventIdSinceNow,
    latency,
    kFSEventStreamCreateFlagNone
  ); 

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

}
예제 #19
0
파일: eyed.c 프로젝트: rsms/eye
int
main(int argc, const char * argv[])
{
  int result = 0;
  FSEventStreamRef streamRef;
  Boolean startedOK;
  int flush_seconds = 3600; // When to force-flush any queued events
  
  if(argc < 2 || strcasecmp(argv[1], "--help") == 0) {
    fprintf(stderr, "usage: %s path ...\n", argv[0]);
    exit(1);
  }
  
  const char **paths = &argv[1];
  streamRef = my_FSEventStreamCreate(paths, argc-1);
  
  FSEventStreamScheduleWithRunLoop(streamRef, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
  
  startedOK = FSEventStreamStart(streamRef);
  if (!startedOK) {
    log_error("FSEventStreamStart(streamRef) failed");
    goto out;
  }
  
  if (flush_seconds >= 0) {
    log_debug("CFAbsoluteTimeGetCurrent() => %.3f", CFAbsoluteTimeGetCurrent());
    CFAllocatorRef allocator = kCFAllocatorDefault;
    CFAbsoluteTime fireDate = CFAbsoluteTimeGetCurrent() + /*settings->*/flush_seconds;
    CFTimeInterval interval = /*settings->*/flush_seconds;
    CFOptionFlags flags = 0;
    CFIndex order = 0;
    CFRunLoopTimerCallBack callback = (CFRunLoopTimerCallBack)timer_callback;
    CFRunLoopTimerContext context = { 0, streamRef, NULL, NULL, NULL };
    CFRunLoopTimerRef timer = CFRunLoopTimerCreate(allocator, fireDate, interval, flags, order, callback, &context);
    CFRunLoopAddTimer(CFRunLoopGetCurrent(), timer, kCFRunLoopDefaultMode);
  }
  
  // Run
  CFRunLoopRun();
  
  // Stop / Invalidate / Release
  FSEventStreamStop(streamRef);
out:
  FSEventStreamInvalidate(streamRef);
  FSEventStreamRelease(streamRef);
  
  return result;
}
예제 #20
0
파일: fse.c 프로젝트: chregu/tmcli
int
main(int argc, char *argv[])
{
    /* Define variables and create a CFArray object containing
	CFString objects containing paths to watch.
	*/
    CFStringRef mypath = CFSTR("/");
    CFArrayRef pathsToWatch = CFArrayCreate(NULL, (const void **)&mypath, 1, NULL);
    void *callbackInfo = NULL; // could put stream-specific data here.
    FSEventStreamRef stream;
    CFAbsoluteTime latency = 3.0; /* Latency in seconds */
	struct stat Status;
 	stat("/", &Status);
	dev_t device = Status.st_dev;
	
	
	CFUUIDRef uuidO;
	CFStringRef uuid;
	uuidO = FSEventsCopyUUIDForDevice(device); 
	uuid = CFUUIDCreateString(NULL, uuidO);
	
	show(CFSTR("%@:256"), uuid);
	
	
	
    /* Create the stream, passing in a callback, */
    stream =  FSEventStreamCreateRelativeToDevice(NULL,
	&myCallbackFunction,
	callbackInfo,
	device,
	pathsToWatch,
	atoi(argv[2]), /* Or a previous event ID */
	latency,
	kFSEventStreamCreateFlagNone /* Flags explained in reference */
	);
	  /* Create the stream before calling this. */
    FSEventStreamScheduleWithRunLoop(stream, CFRunLoopGetCurrent(),         kCFRunLoopDefaultMode);
	FSEventStreamStart(stream);
	//CFRunLoopRun();
	CFRunLoopRunInMode(kCFRunLoopDefaultMode,atoi(argv[1]),false);
	//sleep(10);
	
	
  
}
/**
 * initially this logic was being threaded off using pthreads, but the FSEventStreamCreate call itself has its own threading, and there's no need
 * for this extra layer of threading, especially as it makes it difficult to consume from Java because of the extra complexity of threading in JNI code
 */
void *event_processing_thread( char * path ) {

    char *pathToMonitor =  path ;

    CFStringRef mypath = CFStringCreateWithCString(NULL, pathToMonitor, NULL);
	
    CFArrayRef pathsToWatch = CFArrayCreate(NULL, (const void **)&mypath, 1, NULL);

    CFAbsoluteTime latency = 0.3;
    FSEventStreamRef stream = FSEventStreamCreate(NULL, &file_system_changed_callback, NULL ,
             pathsToWatch, kFSEventStreamEventIdSinceNow, latency, kFSEventStreamCreateFlagNoDefer);
	
    FSEventStreamScheduleWithRunLoop(stream, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
    FSEventStreamStart(stream);
	
    CFRunLoopRun();
    return NULL;
}
예제 #22
0
static FSEventStreamRef add_watch (SeafWTMonitorPriv *priv, const char* repo_id)
{
    SeafRepo *repo = NULL;
    const char *path = NULL;

    repo = seaf_repo_manager_get_repo (seaf->repo_mgr, repo_id);
    if (!repo) {
        seaf_warning ("[wt mon] cannot find repo %s.\n", repo_id);
        return 0;
    }

    path = repo->worktree;
    CFStringRef mypath = CFStringCreateWithCString (kCFAllocatorDefault,
                                                    path, kCFStringEncodingUTF8);
    CFArrayRef pathsToWatch = CFArrayCreate(NULL, (const void **)&mypath, 1, NULL);
    FSEventStreamRef stream;

    /* Create the stream, passing in a callback */
    struct FSEventStreamContext ctx = {0, priv, NULL, NULL, NULL};
    stream = FSEventStreamCreate(kCFAllocatorDefault,
                                 stream_callback,
                                 &ctx,
                                 pathsToWatch,
                                 kFSEventStreamEventIdSinceNow,
                                 1.0,
                                 kFSEventStreamCreateFlagWatchRoot
        );

    CFRelease (mypath);
    CFRelease (pathsToWatch);

    if (!stream) {
        seaf_warning ("[wt] Failed to create event stream \n");
        return stream;
    }

    FSEventStreamScheduleWithRunLoop(stream, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
    FSEventStreamStart (stream);
#ifdef FSEVENT_DEBUG
    FSEventStreamShow (stream);
    seaf_debug ("[wt mon] Add repo %s watch success :%s.\n", repo_id, repo->worktree);
#endif
    return stream;
}
예제 #23
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);
}
예제 #24
0
파일: main.c 프로젝트: 812872970/cxEngine
int main(int argc, const char * argv[])
{
    CFStringRef mypath = CFSTR("/Volumes/BACKUP/images");
    CFArrayRef pathsToWatch = CFArrayCreate(NULL, (const void **)&mypath, 1, NULL);
    FSEventStreamRef stream;
    CFAbsoluteTime latency = 3.0; /* Latency in seconds */
    /* Create the stream, passing in a callback */
    stream = FSEventStreamCreate(NULL,
                                 &fsEventStreamCallback,
                                 NULL,
                                 pathsToWatch,
                                 kFSEventStreamEventIdSinceNow, /* Or a previous event ID */
                                 latency,
                                 kFSEventStreamCreateFlagFileEvents /* Flags explained in reference */
                                 );
    FSEventStreamScheduleWithRunLoop(stream, CFRunLoopGetCurrent(),kCFRunLoopDefaultMode);
    FSEventStreamStart(stream);
    CFRunLoopRun();
    return 0;
}
void QFSEventsFileSystemWatcherEngine::run()
{
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
    threadsRunLoop = CFRunLoopGetCurrent();
    FSEventStreamScheduleWithRunLoop(fsStream, threadsRunLoop, kCFRunLoopDefaultMode);
    bool startedOK = FSEventStreamStart(fsStream);
    // It's recommended by Apple that you only update the files after you've started
    // the stream, because otherwise you might miss an update in between starting it.
    updateFiles();
#ifdef QT_NO_DEBUG
    Q_UNUSED(startedOK);
#else
    Q_ASSERT(startedOK);
#endif
    // If for some reason we called stop up above (and invalidated our stream), this call will return
    // immediately.
    CFRunLoopRun();
    threadsRunLoop = 0;
    QMutexLocker locker(&mutex);
    waitForStop.wakeAll();
#endif
}
예제 #26
0
static void * EventProcessingThread(void *data) {
    CFStringRef path = CFSTR("/");
    CFArrayRef pathsToWatch = CFArrayCreate(NULL, (const void **)&path, 1, NULL);
    void *callbackInfo = NULL;
    CFAbsoluteTime latency = 0.3;  // Latency in seconds

    FSEventStreamRef stream = FSEventStreamCreate(
        NULL,
        &callback,
        callbackInfo,
        pathsToWatch,
        kFSEventStreamEventIdSinceNow,
        latency,
        kFSEventStreamCreateFlagNoDefer
    );

    FSEventStreamScheduleWithRunLoop(stream, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
    FSEventStreamStart(stream);

    CFRunLoopRun();
    return NULL;
}
AppleReloadManager::AppleReloadManager()
{
   //Register with file system

    CFStringRef mypath = CFSTR("assets");
    CFArrayRef pathsToWatch = CFArrayCreate(NULL, (const void **)&mypath, 1, NULL);
    FSEventStreamContext  *callbackInfo = NULL; // could put stream-specific data here.
    auto myCallbackFunction = AppleReloadManager::eventCallback;
    CFAbsoluteTime latency = 3.0; /* Latency in seconds */
    /* Create the stream, passing in a callback */
    stream = FSEventStreamCreate(NULL,
        myCallbackFunction,
        callbackInfo,
        pathsToWatch,
        kFSEventStreamEventIdSinceNow, /* Or a previous event ID */
        latency,
        kFSEventStreamCreateFlagFileEvents /* Flags explained in reference */
    );
   FSEventStreamScheduleWithRunLoop(stream, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
   FSEventStreamStart(stream);
   pthread_mutex_init(&AppleReloadManager::reloadMutex, NULL);
}
예제 #28
0
void watch_directory(VALUE self) {
  VALUE rb_registered_directories = rb_iv_get(self, "@registered_directories");
  int i, dir_size;
  dir_size = RARRAY_LEN(rb_registered_directories);

  VALUE *rb_dir_names = RARRAY_PTR(rb_registered_directories);
  CFStringRef dir_names[dir_size];
  for (i = 0; i < dir_size; i++) {
    dir_names[i] = CFStringCreateWithCString(NULL, (char *)RSTRING_PTR(rb_dir_names[i]), kCFStringEncodingUTF8);
  }

  CFArrayRef pathsToWatch = CFArrayCreate(NULL, (const void **)&dir_names, dir_size, NULL);


  VALUE rb_latency = rb_iv_get(self, "@latency");
  CFAbsoluteTime latency = NUM2DBL(rb_latency);

  FSEventStreamContext context;
  context.version = 0;
  context.info = (VALUE *)self;
  context.retain = NULL;
  context.release = NULL;
  context.copyDescription = NULL;

  stream = FSEventStreamCreate(NULL,
    &callback,
    &context,
    pathsToWatch,
    kFSEventStreamEventIdSinceNow,
    latency,
    kFSEventStreamCreateFlagNone
  );

  FSEventStreamScheduleWithRunLoop(stream, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
  FSEventStreamStart(stream);
  CFRunLoopRun();
}
예제 #29
0
FSEventsWatcher::FSEventsWatcher(QString path) {
  CFStringRef path_to_watch = CFStringCreateWithCString(kCFAllocatorDefault,
                                                        utf8(path).c_str(),
                                                        kCFStringEncodingUTF8);
  CFArrayRef paths_to_watch = CFArrayCreate(NULL, (const void **)&path_to_watch, 1, NULL);

  context_ = new FSEventStreamContext;
  context_->version = 0;
  context_->info = static_cast<void*>(this);
  context_->retain = NULL;
  context_->release = NULL;
  context_->copyDescription = NULL;

  stream_ = FSEventStreamCreate(kCFAllocatorDefault,
                                &FSEventsCallback,
                                context_,
                                paths_to_watch,
                                kFSEventStreamEventIdSinceNow, /* Or a previous event ID */
                                1.0, /* latency in seconds */
                                kFSEventStreamCreateFlagNone);

  FSEventStreamScheduleWithRunLoop(stream_, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
  FSEventStreamStart(stream_);
}
예제 #30
0
void FolderWatcherPrivate::startWatching()
{
    qDebug() << "FolderWatcherPrivate::startWatching()" << _folder;
    CFStringRef folderCF = CFStringCreateWithCharacters(0, reinterpret_cast<const UniChar *>(_folder.unicode()),
                                                        _folder.length());
    CFArrayRef pathsToWatch = CFStringCreateArrayBySeparatingStrings (NULL, folderCF, CFSTR(":"));

    FSEventStreamContext ctx =  {0, this, NULL, NULL, NULL};

    // TODO: Add kFSEventStreamCreateFlagFileEvents ?

    _stream = FSEventStreamCreate(NULL,
                                 &callback,
                                 &ctx,
                                 pathsToWatch,
                                 kFSEventStreamEventIdSinceNow,
                                 0, // latency
                                 kFSEventStreamCreateFlagUseCFTypes|kFSEventStreamCreateFlagFileEvents|kFSEventStreamCreateFlagIgnoreSelf
                                 );

    CFRelease(pathsToWatch);
    FSEventStreamScheduleWithRunLoop(_stream, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
    FSEventStreamStart(_stream);
}