github.com/nycdavid/zeus@v0.0.0-20201208104106-9ba439429e03/vagrant/ext/fsevents/main.m (about) 1 #import <Foundation/Foundation.h> 2 #include <CoreServices/CoreServices.h> 3 #include <sys/stat.h> 4 #include <fcntl.h> 5 6 static CFMutableArrayRef _watchedFiles; 7 static FSEventStreamRef _activeStream; 8 static NSMutableDictionary *_fileIsWatched; 9 10 static int flagsWorthReloadingFor = \ 11 kFSEventStreamEventFlagItemRemoved | \ 12 kFSEventStreamEventFlagItemRenamed | \ 13 kFSEventStreamEventFlagItemModified; 14 15 void myCallbackFunction( 16 ConstFSEventStreamRef streamRef, 17 void *clientCallBackInfo, 18 size_t numEvents, 19 void *eventPaths, 20 const FSEventStreamEventFlags eventFlags[], 21 const FSEventStreamEventId eventIds[]) 22 { 23 int i, flags; 24 char **paths = eventPaths; 25 26 for (i = 0; i < numEvents; i++) { 27 flags = eventFlags[i]; 28 29 if (flags & (kFSEventStreamEventFlagItemIsFile | flagsWorthReloadingFor)) { 30 printf("%s\n", paths[i]); 31 fflush(stdout); 32 } 33 } 34 } 35 36 void configureStream() 37 { 38 if (CFArrayGetCount(_watchedFiles) == 0) return; 39 40 if (_activeStream) { 41 FSEventStreamStop(_activeStream); 42 FSEventStreamUnscheduleFromRunLoop(_activeStream, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); 43 //CFRelease(_activeStream); 44 } 45 46 _activeStream = FSEventStreamCreate(NULL, 47 &myCallbackFunction, 48 NULL, 49 _watchedFiles, 50 kFSEventStreamEventIdSinceNow, 51 1.0, // latency 52 kFSEventStreamCreateFlagFileEvents); 53 54 FSEventStreamScheduleWithRunLoop(_activeStream, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); 55 56 FSEventStreamStart(_activeStream); 57 58 } 59 60 int maybeAddFileToWatchList(char *line) 61 { 62 CFStringRef file = CFStringCreateWithCString(NULL, line, kCFStringEncodingASCII); 63 struct stat buf; 64 65 if ([_fileIsWatched valueForKey:(NSString *)file]) { 66 return 0; 67 } else if (stat(line, &buf) == 0) { 68 [_fileIsWatched setValue:@"yes" forKey:(NSString *)file]; 69 CFArrayAppendValue(_watchedFiles, file); 70 return 1; 71 } else { 72 return 0; 73 } 74 } 75 76 void handleInputFiles() 77 { 78 int anyChanges = 0; 79 80 char line[2048]; 81 82 while (fgets(line, sizeof(line), stdin) != NULL) { 83 line[strlen(line)-1] = 0; 84 anyChanges |= maybeAddFileToWatchList(line); 85 } 86 87 if (anyChanges) { 88 configureStream(); 89 } 90 } 91 92 void configureTimerAndRun() 93 { 94 CFRunLoopTimerRef timer = CFRunLoopTimerCreate(NULL, 95 0, 96 0.5, 97 0, 98 0, 99 &handleInputFiles, 100 NULL); 101 102 CFRunLoopAddTimer(CFRunLoopGetCurrent(), timer, kCFRunLoopDefaultMode); 103 CFRunLoopRun(); 104 } 105 106 int main(int argc, const char * argv[]) 107 { 108 int flags = fcntl(0, F_GETFL); 109 flags |= O_NONBLOCK; 110 fcntl(STDIN_FILENO, F_SETFL, flags); 111 112 _watchedFiles = CFArrayCreateMutable(NULL, 0, NULL); 113 _fileIsWatched = [[NSMutableDictionary alloc] initWithCapacity:500]; 114 115 configureTimerAndRun(); 116 return 0; 117 }