#include <dispatch/dispatch.h>
#include <stdio.h>
+typedef char FlagDescription[8];
+
+void LogControlFlagInfo(dispatch_queue_t log_queue,
+ FSEventStreamEventFlags flags) {
+ if (flags & kFSEventStreamEventFlagUserDropped) {
+ dispatch_async(log_queue, ^{
+ printf("User-side buffer dropped event\n");
+ });
+ } else if (flags & kFSEventStreamEventFlagKernelDropped) {
+ dispatch_async(log_queue, ^{
+ printf("Kernel-side buffer dropped event\n");
+ });
+ } else if (flags & kFSEventStreamEventFlagEventIdsWrapped) {
+ dispatch_async(log_queue, ^{
+ printf("Event IDs have wrapped\n");
+ });
+ }
+}
+
+void DescribeFlags(FSEventStreamEventFlags flags, FlagDescription description) {
+ memset(description, '-', sizeof(FlagDescription));
+ description[sizeof(FlagDescription) - 1] = '\0';
+
+ if (flags & kFSEventStreamEventFlagItemCreated)
+ description[0] = 'C';
+ else if (flags & kFSEventStreamEventFlagItemModified)
+ description[1] = 'M';
+ else if (flags & kFSEventStreamEventFlagItemRemoved)
+ description[2] = 'R';
+ else if (flags & kFSEventStreamEventFlagItemRenamed)
+ description[3] = 'N';
+ else if (flags & (kFSEventStreamEventFlagItemInodeMetaMod |
+ kFSEventStreamEventFlagItemFinderInfoMod))
+ description[4] = 'M';
+ else if (flags & kFSEventStreamEventFlagItemChangeOwner)
+ description[5] = 'O';
+ else if (flags & kFSEventStreamEventFlagItemXattrMod)
+ description[6] = 'X';
+}
+
void EventStreamCallback(ConstFSEventStreamRef event_stream,
void* callback_info,
size_t num_events,
const FSEventStreamEventFlags flags = event_flags[i];
const FSEventStreamEventId ids = event_ids[i];
+ LogControlFlagInfo(log_queue, flags);
+
char* path = strdup(event_paths[i]);
dispatch_async(log_queue, ^{
- printf("event %llx %x at %s\n", ids, flags, path);
+ FlagDescription flag_description;
+ DescribeFlags(flags, flag_description);
+ printf("event %llx %s at %s\n", ids, flag_description, path);
free(path);
});
}
}
int main() {
+ // All logging should happen on a serial queue, so that stdout is not
+ // interleaved, as it could be when handling FSEvents on the concurrent
+ // event queue.
dispatch_queue_t log_queue = dispatch_queue_create("com.google.fseventw.logq", DISPATCH_QUEUE_SERIAL);
dispatch_queue_t event_queue = dispatch_queue_create("com.google.fseventw.eventq", DISPATCH_QUEUE_CONCURRENT);