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  }