/** * 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); }
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; }
//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(); }
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; }
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 }
//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(); }
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; }
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); }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
//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(); }
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; }
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; }
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; }
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); }
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 }
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); }
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(); }
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_); }
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); }